基本的な正規表現の覚書(その1)です。
正規表現は特殊文字であるメタ文字(metacharacter)とメタ文字以外のリテラル(literal)と呼ばれる通常のテキスト文字で構成される。
正規表現の一部を部分パターン呼ぶ。
「te(st|xt)」の場合「(st|xt)」は「te(st|xt)」の部分パターン。
正規表現のメタ文字と正規表現を利用するプログラム言語(JavaScript,PHPなど)の文字列におけるメタ文字は別物。区別をしっかりとする(シェル(DOS, Bbashなど)も同様)。
メタ文字 | 正規表現 | DOSプロンプト | PHPの”文字列内 |
---|---|---|---|
. | メタ文字:任意の一文字 | メタ文字ではない | メタ文字ではない |
? | メタ文字:直前の0or1回繰返し | メタ文字:任意の一文字 | メタ文字ではない |
* | メタ文字:直前の0回以上繰返し | メタ文字:ワイルドカード | メタ文字ではない |
¥t | メタ文字:タブ | メタ文字ではない | メタ文字:タブ |
正規表現「.」は任意の一文字を表すメタ文字。DOSプロンプの.やPHPの文字列としての”.”や’.’はピリオドを表す通常の文字※。
正規表現の「*」は直前の文字の0回以上の繰返しを表すメタ文字。DOSプロンプトではワイルドカードを表すメタ文字。PHPの文字列中の”*”や’*’はアスタリスクを表す通常の文字※。
※1:PHPでは文字列の表記法として”と’で囲む2種類の方法がある。
正規表現のタブを表すメタ文字「\t」とPHPの”文字列内でタブを表すメタ文字”\t”はたまたま同じ表記\t。しかし双方は別物である(\nなども同様)。
c:egrep>egrep "^(?:From|Subject):(.*)" filepath;
DOSプロンプトで”(ダブルクォート)で囲まれた文字列内のメタ文字*はDOSプロンプトのメタ文字*とは解釈されず、通常のリテラル*としてegrepに渡される。egrepは渡された*を正規表現のメタ文字「*」として解釈する。”で囲まない場合、上記の*はDOSプロンプトのメタ文字ワイルドカードとして解釈される。
PHPのmb_ereg_match()は引数として”や’で囲まれた通常の文字列リテラルを受け取る。PHPは”文字列の\tや\nを自身のメタ文字タブ,改行として解釈する。PHPの”文字列内で正規表現のメタ文字として、PHPのメタ文字と重なるメタ文字を渡す場合は\\nのようにをエスケープする必要がある。
PHPの’文字列のメタ文字は’のみである。それ以外の文字(¥n,¥tなど)は通常の文字として正規表現に渡される。
mb_ereg_mach(‘¥t’) ⇒ 正規表現の「¥t」として解釈される。
記号 | “文字列” | ‘文字列’ |
---|---|---|
¥n | ラインフィールド | メタ文字ではない |
¥r | キャリッジリターン | メタ文字ではない |
¥t | タブ | メタ文字ではない |
¥ | バックスラッシュ | 末尾に限りバックスラッシュ |
$ | ドル記号 | メタ文字ではない |
¥” | ダブルクォーテーション | メタ文字ではない |
¥’ | メタ文字ではない | シングルクォーテーション |
正規表現のエスケープは下記の3種類のタイプがある。
?,*,+,{min,max}などは量指定子と呼ばれる。正規表現の基本は最長一致。しかし、量指定子によってマッチを制御することができる。
量指定子?,*,+,{min,max}は、最長一致。つまり少しでも多くマッチしようとする。
例1 : 「([0-9a-zA-Z]+)([0-9]+)」をabc123にマッチさせる
([0-9a-zA-Z]+) ⇒ abc12
([0-9]+) ⇒ 3
例2 : 「”(.*)”」をMy name is “findx” “fine”にマッチさせる
“(.*)” ⇒ “findx” “fine”
※「*」は最長一致のため「.*」は出来るだけ多くの文字とマッチしようとする。そのため、findx” “fine”までマッチする。しかしそのままでは正規表現「”(.*)”」は最後の”とマッチするものがなく、マッチ不成功になる。よって.*は”一文字を譲りfindx” “fineとマッチする。量指定子?,*,+,{min,max}は最長一致だが、全体のマッチの成功を必ず優先させる。全体マッチためには最小限のものを正規表現エンジンへ譲りわたす(上記の例では”一文字を譲る)。
量指定子(?,*,+)に?を付けけた??,*?,+?は最短一致である。つまり少しでも少なくマッチしようとする。
例1 : 「([0-9a-zA-Z]+?)([0-9]+)」をabc123にマッチさせる
([0-9a-zA-Z]+?) ⇒ a
([0-9]+) ⇒ bc12
例2 : 「([0-9a-zA-Z]*?)([0-9]+)」をabc123にマッチさせる
([0-9a-zA-Z]*?) ⇒ なし
([0-9]+) ⇒ abc12
?+,*+,++は?,*,+と同様に最長一致である。しかし?+,*+,++は、?,*,+と異なり、一度マッチしたものは全体マッチのためであっても変更しない。
例1 : 「([0-9a-zA-Z]++)([0-9]+)」をabc123にマッチさせる
([0-9a-zA-Z]+?) ⇒ abc123
([0-9]+) ⇒ マッチ不成功
例2 : 「([0-9a-zA-Z]*+)([0-9]+)」をabc123にマッチさせる
([0-9a-zA-Z]*?) ⇒ abc123
([0-9]+) ⇒ マッチ不成功
正規表現で一致したパターンの一部を、後で利用するため記憶しておく機能を後方参照
文字列 <a href="http://www.example.com/index.html">findxfine</a> 正規表現 <a href="([^"]*)">([^< ]*)</a> 置換文字列 \1 \2; 置換結果 http://www.example.com/index.html findxfine
秀丸では¥1から順に値を取得できます。
No comments yet.
改行と段落タグは自動で挿入されます。
メールアドレスは表示されません。