SublimeText 正規表現を使って複数行検索をする方法
やりたいこと
検索ボタンを押すと
氏名: 山田太郎 住所: aaa 電話: 03-xxxx-xxxx
という部分がヒットして
再び検索ボタンを押すと
氏名: 鈴木二郎 住所: bbb 電話: 03-yyy-yyy
という部分がヒットして…
要するに、氏名・住所・電話の3行をセットで検索したい
ただし、項目名は一致しているものの「山田太郎」「鈴木二郎」などデータの中身は文字列が異なる
こういった規則性はあるけど完全一致ではない、複数行にまたがる文字列を検索するにはどうすればいいのかという解説です
正規表現を使って検索する
結論から言うと
(?s)氏名.+?電話[^\n]+
と検索すると目的の結果が得られます
「Find」ボタンを押すたびに、検索でヒットした箇所がハイライトされて表示されます
上記の例では分かりやすくするために氏名・住所・電話のデータセットだけが出てきていますが
実際のケースでは数万文字の文章の中に不定期に規則性のある文字列が登場し、それを検索すると思ってください
SublimeTextで正規表現の機能を有効にする方法
検索窓を開く
SublimeTextで「Ctrl + F」を押すと検索窓が開きます
Regular expressionをオンにする
検索窓の左側、「.*」のボタンは「Regular expression」といいます
ここをクリックして機能をオンにすると正規表現を使った検索が可能になります
SublimeText 具体的な正規表現の解説
通常の検索
検索窓に「氏名」と入力すると、「氏名」の部分がヒットします
ここまでは普通の検索と一緒です
「.+」 任意の文字列を検索
「.」(ドット)は任意の1文字
「+」(プラス)は1回以上の繰り返し
「.+」は任意の文字の1回以上の繰り返し
「氏名.+」と検索すると「氏名: 山田太郎」の部分が検索にヒットします
再び検索すると「氏名: 鈴木二郎」の部分にハイライトが移動します
デフォルトでは一致するかどうかの判定は行単位で行われます
複数行にまたがった検索をするには工夫が必要です
「(?s)」 複数行検索
「(?s)」で複数行検索
「(?s)氏名.+」と検索すると「氏名: 山田太郎」から「電話: 03-zzz-zzz」の部分まで13行がまとめて検索にヒットします
複数行検索になったことで「.+」の任意の文字列の効果がすべての行のすべての文字列を吸収したような形です
検索範囲を限定する
「(?s)氏名.+電話」と検索すると
「氏名」で始まって「電話」で終わり中間部分は任意の文字列という意味になります
3行目の「電話」に反応してほしかったのですが、13行目の「電話」に反応してしまいました
デフォルトでは正規表現は「最長一致」となっていて、検索結果の一致範囲ができるだけ長くなるようにヒットします
最短一致
「.+」は1個以上の任意の文字列(最長一致)という意味ですが
「.+?」とすることで1個以上の任意の文字列(最短一致)という意味になります
「(?s)氏名.+?電話」と検索すると
氏名: 山田太郎 住所: aaa 電話
という部分がヒットしました
「電話」の部分で途切れてしまいましたが
「03-xxxx-xxxx」までを検索結果に含めたいです
「[^\n]+」 改行記号以外の任意の文字列
「(?s)氏名.+?電話[^\n]+」と検索すると
氏名: 山田太郎 住所: aaa 電話: 03-xxxx-xxxx
という部分がヒットします
「\n」は改行記号
「[^\n]」は改行記号以外の任意の文字
「[^\n]+」は改行記号以外の任意の文字の1回以上の繰り返し
分かりやすく言うと「行末までのすべての文字」という意味です
「(?s)氏名.+?電話[^\n]+」の「氏名」の部分が
氏名
に一致して
「(?s)氏名.+?電話[^\n]+」の「.+?」の部分が
: 山田太郎 住所: aaa
に一致して
「(?s)氏名.+?電話[^\n]+」の「電話」の部分が
電話
に一致して
「(?s)氏名.+?電話[^\n]+」の「[^\n]+」の部分が
: 03-xxxx-xxxx
に一致するので
「(?s)氏名.+?電話[^\n]+」という正規表現検索トータルでは
氏名: 山田太郎 住所: aaa 電話: 03-xxxx-xxxx
という部分がヒットするという仕組みです
まとめ
「(?s)」は複数行検索
「.+?」は任意の文字の1回以上の繰り返し、最短一致
「[^\n]+」は改行以外の任意の文字の1回以上の繰り返し
コメント