2021.11.07 追記
本記事は、個人的な学習の記録です。
本で分からなかったことの補足
「PHPしっかり入門教室」を読んでいます。
正規表現の頁に差し掛かって、さっそく分からない部分があったので調べたいと思います。
「\A」・「\z」と「^」・「$」はどう違うのか、どちらを使えばいいのか
「PHPしっかり入門教室」の正規表現の頁を見ると、二者の違いに関してこう書かれています。
文字列の始まりは「\A」以外に「^」、「\z」以外に「$」を使用することもできます。ただし、こちらは行の始まりや終わりを表すので、間に改行コードがあっても無視されます。一方「\z」は改行コードが入る直前を意味しています。
そもそもここで「???」となりました。
なので、こちらのブログ記事を見てみると、『「\A」と「\z」を使いましょう』とあります。
▼正規表現によるバリデーションでは ^ と $ ではなく \A と \z を使おう | 徳丸浩の日記
記事の例を借ります。
以下の文字列に対して、
javascript:exploit_code();/*
http://hi.com
*/
下記パターンを指定すると、
/^https?:\/\/[^\n]+$/i
文字列http://hi.com
がマッチします。(Rubyの場合)
※実際の結果(Rubularに飛びます。)
パターンを見ると、文字列の始まりは『「http」か「https」のどちらか』になっています。
対象文字列を見ると、二行目は合致していますが、一行目は合致していません。
同じパターン、同じ文字列で今度はPHPの場合だとどうなるか試してみます。
※実行結果(regex101に飛びます)
結果は、「どの文字列にもマッチしない」となりました。
regex101で使えるデバッガーを使ってみると、以下のことがわかります。
- 指定したパターンでは1行目しかチェックしない
改めて最初に挙げた徳丸さんの記事を見ると、「Rubyの正規表現機能は、デフォルトで複数行モードである」との記載があります。これのおかげで(?)RubyとPHPでは同じ正規表現パターンでも違う結果が出るんですね。
行先頭で判断するか否か
「^」を使うと、行の先頭に指定の文字列が含まれていればマッチすることになります。
「\A」を使うと、文字列の先頭に指定の文字列が含まれていればマッチすることになります。
...と、それっぽく書いたは良いのですが、結局「行の先頭」と「文字列の先頭」の意味の違いがわからず。
PHPの場合、こういう認識でいればいいのでしょうか。。
- 複数行モードのとき:「文字列の先頭」(\A)の指定の仕方だと2行目以降にマッチする文字列があってもマッチしない
- 単一行モードのとき:\Aも^も同じ
つまり
今の段階では「\A」と「\z」を使うのをデフォルトにしておけば良いということなんでしょうかね...。(まずは勉強を続けます(T_T))
参考
▼PHPしっかり入門教室(「翔泳社の本」に飛びます)