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);
とかしてやればOK。
ただ、文字列リテラルでシングルクォーテーションを使う分にはこれで良いけど、
ダブルクォーテーションで変数を展開する場合は別な問題があったり。
例えば、
$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 以外の他の正規表現関数でも同じ。