TITLE:間違いだらけの正規表現講座 level 7
#contents
* れっつ練習! [#vdcb7bcb]
さて、駆け足でやってきましたが、第6回までの説明で、~
正規表現での検索の基本の部分は押さえたことになります。
次回からは、正規表現の真骨頂、正規表現を使った置換のやりかたを見ていきますが、~
ここらで一旦おさらいを兼ねて、検索の練習をしてみましょう。
* おさらい [#baac8c4b]
まずは、今まで出てきたメタ文字をおさらいしましょう。
|メタ文字|意味|出てきた回|h
|.|任意の1文字にマッチ|[[第1回>その他雑文/正規表現/1]]|
|[abc]|[]内のどれか1文字にマッチ|[[第1回>その他雑文/正規表現/2]]|
|[a-z]|[]内のa~zにマッチ|[[第2回>その他雑文/正規表現/2]]|
|[^abc]|[]内以外の任意の1文字にマッチ|[[第2回>その他雑文/正規表現/2]]|
|*|直前の正規表現の、0回以上の繰り返し|[[第3回>その他雑文/正規表現/3]]|
|+|直前の正規表現の、1回以上の繰り返し|[[第3回>その他雑文/正規表現/3]]|
|?|直前の正規表現の、0回もしくは1回の繰り返し|[[第3回>その他雑文/正規表現/3]]|
|()|()内の正規表現を、まとめて1つの正規表現として扱う|[[第4回>その他雑文/正規表現/4]]|
|\t|タブ記号|[[第5回>その他雑文/正規表現/5]]|
|\r|改行記号 0D|[[第5回>その他雑文/正規表現/5]]|
|\n|改行記号 0A|[[第5回>その他雑文/正規表現/5]]|
|\|直後の記号をエスケープする|[[第5回>その他雑文/正規表現/5]]|
|^|先頭にマッチ|[[第6回>その他雑文/正規表現/6]]|
|$|終端にマッチ|[[第6回>その他雑文/正規表現/6]]|
* 例題 [#l65a455c]
では、例題です。HTMLのようなもの。
正規表現テスターを立ち上げ、以下の文章をコピペして、チャレンジしてみてください。~
上手く行ったら、自分の使っているエディタに正規表現の機能があるかどうか調べ、~
そのエディタでも試してみましょう。
なお、正規表現テスターでは、
-シングルラインモードON/OFFは、『「.」が改行にもマッチする』(チェックでON)
-マルチラインモードON/OFFは、『「^$」が各行毎にマッチする』(チェックでON)
-改行記号は \n
となっています。
#HTMLのようなもの。
#これはコメントです。
<html>
<a href="01234.html">電話番号#1="012-3456-7890"</a>
<a href="56789.html">電話番号#2="090-0000-0000"</a>
<a href="kenokeno.html">へもへも</a>
<a href="kenokeno.html">へもへもへも</a>
<a href="mononoke.html">ものへも
</a>
</html>
- 電話番号(012-3456-7890とか)にマッチする正規表現を書け。
- 数字で出来たファイル名だけ(01234.htmlとか)にマッチする正規表現を書け((ヒント:「.」はメタ文字です!))
- 「<a href="~">」の部分にマッチする正規表現を書け((ヒント:途中の空白が何文字か決まっていませんね))
- へも、の繰り返しで出来ている部分にマッチする正規表現を書け((ヒント:「へも」を単位とした繰り返しです))
- タグ(<と>で囲まれたもの)に全てマッチする正規表現を書け((ヒント:シングルラインモードは?))
- コメントっぽい行(最初の2行)にマッチする正規表現を書け((ヒント:行の頭が#で始まっていますね))
- 行内で完結しているリンク(<aで始まり/a>で終わる)にマッチする正規表現を書け((ヒント:シングルラインモードは?))
- 全てのリンクにマッチする正規表現を書け((ヒント:最後のリンクはどうしましょう))
* 欲張りなマッチと欲張りでないマッチ [#h8c05c43]
さて、最後の問題が厄介だったのではないでしょうか。~
多分、単純に「<a.*/a>」などとすると、最後のリンクは改行が混じっているので
マッチできませんね。
仕方ないので、シングルラインモード(「.」が改行にもマッチする)を~
チェックして試してみると、今度は、4つのリンクが全部いっぺんにマッチして~
しまった筈です。
これは、第3回でちらっと述べた、「最長一致の法則」、別名「強欲なマッチ」~
という仕様が関係しています。
「.」は、マッチできる限り最長の文字列にマッチしようとします。~
「.」が改行にマッチしない場合(シングルラインモードOFF)であれば、~
「.*」は改行のところで有効範囲が切れるのですが、
「.」が改行にマッチするようにすると、~
何行も何行も延々とマッチし続けてしまうのですね。
つまり、『「<a」で始まって、改行を含む何文字かがあって、「/a>」で終わる』~
最長の文字列を探してしまうわけで、途中に「<a」や「/a>」が含まれていても、~
それは「.*」の一部分と考えられてしまうわけです。
このような場合に使うのが、「最短一致」です。
「*」「+」の後に「?」をつけると、その場合だけ、「*」「+」は、~
「可能な限り最短の文字列にマッチ」するようになります。
シングルラインモードONの状態で、「<a.*?/a>」で検索して試してみてください。~
今度は上手く行く筈です。
この場合、『「<a」で始まって、改行を含む何文字かがあって、「/a>」で終わる』~
という最短の文字列を探すので、このような動作になります。
というわけで、メタ文字の一覧に追加です。
|メタ文字|意味|h
|*?|直前の正規表現の、0回以上の繰り返し(最短一致)|
|+?|直前の正規表現の、1回以上の繰り返し(最短一致)|
* ご指摘などはこちらへ [#kedca7c3]
#comment