VZユーザーのための,VWXによる正規表現利用のてびき
初出:nifty:FGALDC/MES/13/09142〜 (2002/06/18〜2002/07/21)
重要な問題として,「最長一致」があります。
これは,パターンが複数の文字列にマッチするときは,最も長い文字列が選択されるということです。これを見誤ると,予測しない部分を含んでマッチしてしまいます。検索の場合はごみ拾いや検索漏れを起こし,置換の場合は予定外の部分を削除してしまうことになります。このへんは正規表現が敬遠される理由のひとつかもしれません。
HTML文書があるとします。タグが付与されたままだとエディタでは読みにくいので,タグ部分を削除して読みやすくしてみようと思います。
【<.+>】 → 【】
これで『<』と『>』に挟まれた部分が『<』『>』とともに消えてくれるはずですね。
さて,実行して見るとびっくり。標題がすっかり消えてしまっています。それだけでなく,本文も大量に失われているではありませんか。これは何故でしょう。
<h1>正規表現入門</h1>
このような行の場合,期待したのは『<h1>』と『</h1>』の削除だったのですが,実際には行頭の『<』から行末の『>』までがそっくり削除されてしまいました。これが最長一致の現象です。
普通,人間の目視では(右脳の発達などにもよるのかもしれませんが),スポットライトを当てたようにかなり狭い範囲で一致する部分を判定しようとしますから,正規表現とのずれは仕方がないところです。これは慣れるしかないでしょう。失敗を積み重ねて初めて会得するものだと思います。
さて,上のような場合の解決策ですが,テキスト処理の基本である「テキスト」の解析を試みてみましょう。まず一致させたいパターンを文字の種類で分解してみます。
< h 1 >
『<』と『>』の間に文字列が入っています。この文字列は,先の見出しのように単純な場合もあれば,
<img sorce="mana" alt="買い物帰りの真魚" width="240" height="160">
…のように,アスキー,2バイト文字,スペースが混在する場合もあります。これを正規表現で書くと,どうやっても<.+>となってしまうではありませんか。うーむ,それでは『>』と『<』およびその間の文字を含んでしまって,結局行末の『>』まで丸ごとマッチしてしまいます。困りましたね。
<h1>第1部 旅の仲間</h1> <--------------> 残したい部分 <-----------------------> マッチしてしまう部分
いや,待ってください。『<』と『>』を含まない文字列ならいいわけですよね。確か特定の文字を除外する方法があったはずです。
これこれ。(^^)
『<』と『>』を含まない文字列なら[^<>]で,任意の文字数があれば[^<>]+ということになりますね。さて,それでは試してみましょう。
【<[^<>]+>】 → 【】
やりました! 大成功です。(^^)
実際には,ひと組の『<』と『>』の間に『<』が出てくることはありませんから,
【<[^>]+>】 → 【】
…でも十分ですね。
最長一致しては困るという場合は,このようにテキストの構造を研究することになります。テキストの構造を研究するということは,正規表現を特に必要としないテキストの整形にも大変役に立ちますので,日ごろから「この文書はこんな構造になっているな」などと考えて見るのも愉快な訓練だと思います。