先読みと後読みを理解する
正規表現を学んでいくと出会うのが,
先後読みを使いこなすと,
ここでは,
先後読みはゼロ幅マッチ
正規表現のメタ文字には文字自体にマッチするもののほか,
ゼロ幅マッチは,^
,$
,\b
はゼロ幅マッチです。そして重要なのが,
ゼロ幅マッチはマッチ文字列に入ることがないので,s///
で文字列置換の対象に入ることがありません。このことを指して,
- 注1)
- ゼロ幅であることを強調して,
ゼロ幅の言明と呼ばれることもあります。
先後読みの記法
先読みと後読みにはそれぞれ肯定と否定があり,
表3 先後読みのメタ文字
メタ文字 | 名前 | 説明 |
---|---|---|
(?=●) | 肯定の先読み | この位置の右側が正規表現●にマッチすることを要請 |
(?!●) | 否定の先読み | この位置の右側が正規表現●にマッチしないことを要請 |
(?<=●) | 肯定の後読み | この位置の左側が正規表現●にマッチすることを要請 |
(?<!●) | 否定の後読み | この位置の左側が正規表現●にマッチしないことを要請 |
まず, 正規表現 この例だと 初学者が先後読みを学んだ際, 前項の しかし, 時間軸で考える場合も, 「後」 先読みや後読みはゼロ幅マッチであると解説しましたが, 図1では このように,
my $intro = "私は牛乳と牛丼が好きです";
$intro =~ s/牛(?=丼)/豚/g;
print "$intro\n"; # => 私は牛乳と豚丼が好きです
牛(?=丼)
は,牛
の右側に丼
がある場合,牛
にマッチします。丼
は先読み(?=丼)
によってマッチに必要な条件ですが,丼
という文字を消費しません)。そのため,牛
となり,牛丼
のみ豚丼
に置換されます。s/牛丼/豚丼/g
でも代用できます。しかし,先や後はマッチカーソルの動き
s/牛(?=丼)/豚/g
のサンプルは,牛
の後に丼
がある場合」牛
をマッチ文字列候補に取り込んだけれど,
perldoc perlre
などの公式ドキュメントでは,ゼロ幅マッチは一段下げて読む
牛(?=丼)
を例として,(?=丼)
を下の行に移しています。ゼロ幅マッチが位置にマッチすることと,