文字列のパターン検索に使われる「正規表現」。といっても、統一した記法があるわけではなく、アプリケーションや、言語によって、書き方や仕様が異なっています。
しかし、最近はPerlでの正規表現に準じた書き方が標準になりつつあるので、おおまかには、Perlでの書き方を中心に考えていけばよいようです。
文字列の単純な検索を行って違いを見ます。検索結果の文字列は「,」で区切って表示しています。
言語 | ソース | 結果 |
---|---|---|
お題:空マッチ 文字列 "123456789" を 空パターン () で一括検索する。 | ||
Perl.5.12 | /()/g | ,,,,,,,,, |
javascript IE8 | "123456789".match(/()/g) | ,,,,,,,,, |
cextra | echo 123456789|cextra "()" -xt, -hg1 | ,,,,,,,, |
cextra | echo 123456789|cextra "()" -xt, -hg1 -hl | ,,,,,,,,, |
cextra | echo 123456789|cextra "()" -xt, -hg2 | ,,,,,,,,, |
cextra | echo 123456789|cextra "()" -xt, -hg3 | ,,,,,,,,, |
cextra | echo 123456789|cextra "()" -xt, -hg3 -hl | ,,,,,,,,, |
お題:選択肢と空マッチ 文字列 "123456789" を 選択肢の付いた空パターン (|\d) で一括検索する。 | ||
Perl.5.12 | /(|\d)/g | ,1,,2,,3,,4,,5,,6,,7,,8,,9, |
javascript IE8 | "123456789".match(/|\d/g) | ,,,,,,,,, |
cextra | echo 123456789|cextra "|\d" -xt, -hg1 | ,,,,,,,, |
cextra | echo 123456789|cextra "|\d" -xt, -hg1 -hl | ,,,,,,,,, |
cextra | echo 123456789|cextra "|\d" -xt, -hg2 | ,1,2,3,4,5,6,7,8,9 |
cextra | echo 123456789|cextra "|\d" -xt, -hg3 | ,1,,2,,3,,4,,5,,6,,7,,8,,9 |
cextra | echo 123456789|cextra "|\d" -xt, -hg3 -hl | ,1,,2,,3,,4,,5,,6,,7,,8,,9, |
お題:全マッチ 文字列 "123456789" を 全マッチ (.*) で一括検索する。 | ||
Perl.5.12 | /(.*)/g | 123456789, |
javascript IE8 | "123456789".match(/.*/g) | 123456789, |
cextra | echo 123456789|cextra ".*" -xt, -hg1 | 123456789 |
cextra | echo 123456789|cextra ".*" -xt, -hg1 -hl | 123456789, |
cextra | echo 123456789|cextra ".*" -xt, -hg2 | 123456789 |
cextra | echo 123456789|cextra ".*" -xt, -hg3 | 123456789 |
cextra | echo 123456789|cextra ".*" -xt, -hg3 -hl | 123456789, |
ここでチェックしたのは、結果が0幅になる可能性のあるものです。
一括検索(グローバル検索)では、一般的には、次の手順で行っています。
問題になるのは、一致の結果が長さ0の文字列、つまり、0幅の場合です。このとき、次の検索開始位置は、現在の検索開始位置と同じになってしまいます。同じ位置から同じ検索をするのですから、何度繰り返しても同じことになり、結局、無限ループになってしまいます。
これを避けるために、0幅の後、特別な処理をして、なんとか、検索ポイントを進めるようにしています。このときの論理は、「正規表現」で規定されているわけではなく、それぞれの処理系で工夫しているようです。従って、この動作に頼った書き方は、あまり、芳しくありません。
cextra.exe では、この動作を実験するために、次の4種類のモードを搭載し、オプション指定で切り替えて試せるようにしてあります。(通常は使う必要がありませんが…)
特に考慮しない。 | |
0幅マッチの後は1文字分強制的に進める。 | |
最初の1回を除き、検索開始位置での0幅マッチをしない。 | |
0幅マッチの直後は(検索開始位置は変わらないが)、検索開始位置での0幅マッチをしない。(デフォルト) |
また、通常は行末での空マッチを行わないようにしていますが、これを許可するオプション(-HL)もあります。
結果から推測すると、javascript では、-HG1 -HL を指定した場合と同じように動作するようです。 また、perl は、-HG3 -HL を指定した場合と同じように動作するようです。