Posted at

[php] \(半角バックスラッシュ)を文字列置換したい場合の注意点

More than 3 years have passed since last update.

一時的に「!?」ってなったのでメモ。

文字列$nameに半角バックスラッシュが入っていた場合は、全角にしてやろうとした時のこと。


間違い

近辺で、似たような文字列置換をpreg_replace()で書いていたので

ここもpreg_replace()で書いたところ


エラーになります

//nameに半角バックスラッシュが入っていた場合は全角に変換

$name = preg_replace('/\\/u', '\', $name);

これだとエラーになってしまい、$nameにはNULLが入ってしまうのです。


正解

そして、


正解

//nameに半角バックスラッシュが入っていた場合は全角に変換

$name = preg_replace('/\\\/u', '\', $name);

これならおkなんですね。


何故?

\ にマッチングさせる場合は \\ で良いんじゃないのか!?

なんでエスケープが1つ余計に必要なんだ?と思い

先輩方に疑問を投げたところ


推測だけど、 '/\\/u' の場合

2個目のバックスラッシュが正規表現最後のスラッシュ(デリミタ)をエスケープしてしまうからでは?


や、


php側でのエスケープと、PCREでのエスケープが2重でかかってるからなんだろうね。


等の回答を頂きました。なるほど。

preg_replace('/\\\/u', '\', $name);

↓ php的に「\\」が1つの「\」だと認識される

$nameに「\\」があった場合「\」に置換

↓ 正規表現的に「\\」が1つの「\」だと認識される

$nameに「\」があった場合「\」に置換

こういうことかー!


結論

そもそも、正規表現使ってない文字列置換でpreg_replace()使う必要無いよね?

PHP: str_replace - Manual にも


(正規表現のような) 技巧的な置換ルールを必要としない場合、 preg_replace() の代わりにこの関数を常用するべきです。


って書いてある。

…という訳で、


結局…

//nameに半角バックスラッシュが入っていた場合は全角に変換

$name = str_replace('\\', '\', $name);

str_replace()に落ち着きました…