MW211 EXIT

devlog
PHP/バックスラッシュ
2012年04月08日
PHPにおいて、「'」(もしくは「"」)で囲われた文字列中の
「\」(バックスラッシュ)は特別な意味をもつ…らしい。

どんな、特別な意味を持つのか、echoしてみれば一目瞭然
┌──────────────────────────────────────┐
│echo '\';       →閉じるの「'」をエスケープしてしまいエラー                 │
│echo '\\';      →「\」                                                     │
│echo '\\\';     →閉じるの「'」をエスケープしてしまいエラー                 │
│echo '\\\\';    →「\\」                                                    │
│echo '\d';      →「\d」                                                    │
│echo '\\d';     →「\d」                                                    │
│echo '\\\d';    →「\\d」                                                   │
│echo '\\\\d';   →「\\d」                                                   │
└──────────────────────────────────────┘

つまりは、以下のとおり。
  (1) 「\」は直後の文字をエスケープする(エスケープ用文字)
  (2) 「\\」は文字としての「\」に変換される(先頭から順に)
  (3) よって、連続する「\」の数が奇数の場合、最後の「\」はエスケープ用文字となる
  (4) エスケープ用文字「\」は「'」や「"」など、文字囲いには影響を与えるが
      いわゆる正規表現の文字(\dや\w)となっても、
      その文字列なだけでその中身([0-9]とか)にはならない

「preg_match()」など正規表現を使う時には、まず上記の一時変換がなされた後に
その結果を元に正規表現として変換するので
「preg_match('/\d/',…)」も「preg_match('/\\d/',…)」も
「\d」と入力されたのと同じものとして、「[0-9]」的なものに変換される。

但し、「\」を検索文字としたい場合には、正規表現上「\\」でなければならず
そのように変換される元の文字は「\\\\」(もしくは「\\\」)なので
「preg_match('/\\\\/',…)」とPHP上は表記することになる。
※「\\\」が許容されるのは「/\\\/」が「/」+「\\」+「\/」と区切られるのではなく
  「/」+(「\\」+「\」)+「/」と区切られるからのようだ

つまり「preg_match('/\\d/',…)」的な方が正しいのかもしれないが
結果オーライで「preg_match('/\d/',…)」が使用されているのが多数派。
ただし「preg_match('/\\\\/',…)」の意味がよくわからなくなり
「preg_match('/\\\/',…)」も許容されるので訳がわからなくなるという感じか。
分類:PHP