[PHP] PHP における正規表現のデリミタ

この記事は3年以上前に書かれた記事です。情報が古い可能性があります。

PHP の正規表現で使えるデリミタは “/” だけではなかった。

preg_match('/^abc$/', $str);

というような記述を常用しているのだけど、これは

preg_match('{^abc$}', $str);

とか

preg_match('(^abc$)', $str);

みたいに “{” と “}” や “(” と “)” でもいける。(”{}” は perl っぽいか)

ちなみに、なぜこれに気づいたかというと、

preg_match('/^' . $pattern . '/', $str);

という風に、正規表現パターン指定に変数を使う場面があって、そのパターンが “http://” とか “https://” みたいに “/” を含む場合、

preg_match('/^http///', $str);

とかになるので、この呼び出しが失敗していたのです。まぁ、当然ですね。

で、その場合は

preg_match('/^http\/\//', $str);

という具合にエスケープしてやる必要があるけど、それがいちいち面倒。

そんなときに便利なのが “/” 以外のデリミタ。

preg_match('{^http//}', $str);

とか書けばスッキリする。

ただ、文字列リテラルでシングルクォーテーションを使う分にはこれで良いけど、ダブルクォーテーションで変数を展開する場合は別な問題があったり。

例えば、

$str = "abc";
print('$str');

とすると、

$str

とそのまま出力される。

$str = "abc";
print("$str");

とすると、$str の内容が展開されて

abc

と出力される。

また、

$str = "abc";
print("$strrrr");

これは これは abcrrr とはならず、

$strrrr

とそのまま出力される。

こんなときどうするかというと、変数部分を { } で括りますよね。

$str = "abc";
print("{$str}rrr");

これなら

abcrrr

と出力される。

さて、件の正規表現です。

$pattern = "http://";
preg_match("{$pattern}", $str);

こう書くと、おかしなことになる。

preg_match("http://", $str);

となって、デリミタが消えてしまう。なので、やるなら

preg_match("($pattern)", $str);

という風に { } 以外のデリミタを使うか、

preg_match("{" . $pattern . "}", $str);

とかでもいける。

これは preg_match 以外の他の正規表現関数でも同じ。

それにしても、これはなかなか PHP 実装の苦労の跡が感じられますね。

タイトルとURLをコピーしました