/m 修飾子の有無による正規表現の意味の違いは以下のように定義されている。
/m 修飾子無し | /m 修飾子有り | |
\A | 文字列の開始 | 文字列の開始 |
\Z | 文字列の終端または文字列の終端の改行前 | 文字列の終端または文字列の終端の改行前 |
\z | 文字列の終端 | 文字列の終端 |
^ | 文字列の開始 | 行の先頭 |
$ | 文字列の終端または文字列の終端の改行前 | 文字列の終端または行の終端の改行前 |
さまざまな文字列のパターンに対して、文字列中の要素(「文字列の開始」など)位置を示すオフセットを書き出すと以下のようになる。
文字列 | 行 | |||||
開始 | 終端の改行前 | 終端 | 先頭 | 終端の改行前 | 終端 | |
"" | 0 | - | 0 | 0 | - | 0 |
"\n" | 0 | 0 | 1 | 0 | 0 | 1 |
"aa" | 0 | - | 2 | 0 | - | 2 |
"aa\n" | 0 | 2 | 3 | 0 | 2 | 3 |
"aa\nbb" | 0 | - | 5 | 0,3 | 2 | 3,5 |
"aa\nbb\n" | 0 | 5 | 6 | 0,3 | 2,5 | 3,6 |
上に挙げた文字列に対して m//g と m//mg を行い、マッチングの終了した位置を先頭から順に pos 関数で書き出した結果が以下である。
m/\A/ | m/\Z/ | m/\z/ | m/^/ | m/$/ | ||||||
/g | /mg | /g | /mg | /g | /mg | /g | /mg | /g | /mg | |
"" | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
"\n" | 0 | 0 | 0,1 | 0,1 | 1 | 1 | 0 | 0 | 0,1 | 0,1 |
"aa" | 0 | 0 | 2 | 2 | 2 | 2 | 0 | 0 | 2 | 2 |
"aa\n" | 0 | 0 | 2,3 | 2,3 | 3 | 3 | 0 | 0 | 2,3 | 2,3 |
"aa\nbb" | 0 | 0 | 5 | 5 | 5 | 5 | 0 | 0,3 | 5 | 2,5 |
"aa\nbb\n" | 0 | 0 | 5,6 | 5,6 | 6 | 6 | 0 | 0,3 | 5,6 | 2,5,6 |
上のテーブルは下のスクリプトを用いて作成した。
#!/usr/bin/perl -w use strict; use warnings; my @regex = qw(\A \Z \z ^ $); print "<table>\n"; print "<tr><td></td>"; foreach (@regex) { print qq(<td colspan="2">m/$_/</td>); } print "</tr>\n"; print "<tr><td></td>"; foreach (@regex) { foreach my $mod (qw(g mg)) { print qq(<td>/$mod</td>); } } print "</tr>\n"; foreach my $src ("", "\n", "aa", "aa\n", "aa\nbb", "aa\nbb\n") { my $src0 = $src; $src0 =~ s/\n/\\n/g; print qq(<tr><td>"$src0"</td>); foreach my $regex (@regex) { print "<td>"; while ($src =~ m/($regex)/g) { print pos $src, ','; } print "\x08</td>"; print "<td>"; while ($src =~ m/($regex)/mg) { print pos $src, ','; } print "\x08</td>"; } print "</tr>\n"; } print "</table>\n";
具体的に置換を行った結果が以下。
s/\A/|/ | s/\Z/|/ | s/\z/|/ | s/^/|/ | s/$/|/ | ||||||
/g | /mg | /g | /mg | /g | /mg | /g | /mg | /g | /mg | |
"" | "|" | "|" | "|" | "|" | "|" | "|" | "|" | "|" | "|" | "|" |
"\n" | "|\n" | "|\n" | "|\n|" | "|\n|" | "\n|" | "\n|" | "|\n" | "|\n" | "|\n|" | "|\n|" |
"aa" | "|aa" | "|aa" | "aa|" | "aa|" | "aa|" | "aa|" | "|aa" | "|aa" | "aa|" | "aa|" |
"aa\n" | "|aa\n" | "|aa\n" | "aa|\n|" | "aa|\n|" | "aa\n|" | "aa\n|" | "|aa\n" | "|aa\n" | "aa|\n|" | "aa|\n|" |
"aa\nbb" | "|aa\nbb" | "|aa\nbb" | "aa\nbb|" | "aa\nbb|" | "aa\nbb|" | "aa\nbb|" | "|aa\nbb" | "|aa\n|bb" | "aa\nbb|" | "aa|\nbb|" |
"aa\nbb\n" | "|aa\nbb\n" | "|aa\nbb\n" | "aa\nbb|\n|" | "aa\nbb|\n|" | "aa\nbb\n|" | "aa\nbb\n|" | "|aa\nbb\n" | "|aa\n|bb\n" | "aa\nbb|\n|" | "aa|\nbb|\n|" |
上のテーブルは下のスクリプトを用いて作成した。
#!/usr/bin/perl -w use strict; use warnings; my @regex = qw(\A \Z \z ^ $); print "<table>\n"; print "<tr><td></td>"; foreach (@regex) { print qq(<td colspan="2">s/$_/|/</td>); } print "</tr>\n"; print "<tr><td></td>"; foreach (@regex) { foreach my $mod (qw(g mg)) { print qq(<td>/$mod</td>); } } print "</tr>\n"; foreach my $src ("", "\n", "aa", "aa\n", "aa\nbb", "aa\nbb\n") { my $src0 = $src; $src0 =~ s/\n/\\n/g; print qq(<tr><td>"$src0"</td>); foreach my $regex (@regex) { my $dst = $src; $dst =~ s/($regex)/|/g; $dst =~ s/\n/\\n/g; print qq(<td>"$dst"</td>); $dst = $src; $dst =~ s/($regex)/|/mg; $dst =~ s/\n/\\n/g; print qq(<td>"$dst"</td>); } print "</tr>\n"; } print "</table>\n";