見出し画像

[PHP]preg_matchでバックスラッシュ「\」をマッチさせる。

こんにちは、SESエンジニアのつくねん。です。
最近開発した機能で
値にバックスラッシュが含まれる場合php側で全角に変換する。
という要件のものを実装しました。

まず、値に含まれるかの判断処理としてpreg_matchで一致したらと思い

$text = "バックスラッシュ\を含む";

preg_match("/\\/", $text);

としたところ
おや、、マッチしない。
ということでpreg_matchについて調べ直しました。

preg_matchの使い方

preg_match("検索する値(正規表現)", "検索対象文字列")

として、第二引数がマッチすれば1(int)を返す。
今回の場合は
検索する値(正規表現)にバックスラッシュを
検索対象文字列に値(入ってくる値)を入れれば良いはず。

特殊文字のエスケープ

正規表現での特殊文字はエスケープが必要。
バックスラッシュもその1つで「\」は「\\」とする必要がある。


あれ、おかしいな。
問題ないはずなのに、と思い再度preg_matchのphpマニュアルを見ます。

PHPマニュアルで確認

phpのマニュアルでpreg_matchを確認。
すると、User Contributed Notesに下記がありました。

Matching a backslash character can be confusing, because double escaping is needed in the pattern: first for PHP, second for the regex engine

https://www.php.net/manual/ja/function.preg-match.php#108209

Google翻訳で直訳すると
"バックスラッシュ文字の一致は、パターンで二重のエスケープが必要なため、混乱を招く可能性があります。
最初は PHP の場合、2 番目は正規表現エンジンの場合です。"

なるほど、php、正規表現で二重にエスケープが必要なのか。
下記に修正して動作確認をします。

$text = "バックスラッシュ\を含む";

preg_match("/\\\/", $text);

これで取得成功。
一応マニュアルでエスケープシーケンスに関して確認してみると

注意:
シングルクォートあるいはダブルクォートで囲まれた PHP の 文字列 の中では、バックスラッシュは特別な意味を表します。 そのため、正規表現 \\ を使用して \ とマッチさせたい場合は PHP のコード内では "\\\\" あるいは '\\\\' と記述する必要があります。

https://www.php.net/manual/ja/regexp.reference.escape.php

とありました。
なので正確には

$text = "バックスラッシュ\を含む";

preg_match("/\\\\/", $text);

になるらしいです。(なぜ「/\\\/」でも一致するのでしょうか??)


エスケープややこしいですね。。。
解決できてよかったですが、また忘れそうです。
一つずつ分解して覚えておこうと思います。

この記事が気に入ったらサポートをしてみませんか?