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