Quantcast
Viewing all articles
Browse latest Browse all 331

preg_matchが2を返す

https://bugs.php.net/bug.php?id=78853

preg_matchは、パターンにマッチした場合は1を、マッチしなければ0を、エラーが発生したらfalseを返します。

Image may be NSFW.
Clik here to view.
01.png

ということでこんな正規表現を試してみましょう。

var_dump(preg_match('/^|\d{1,2}$/',"7"));

結果

Image may be NSFW.
Clik here to view.
02.png

なんだこれ?

2が返ってきました。
英語版にもしっかり"1か0かfalseを返す"と書いてあって、ドキュメントの更新漏れとかでもなさそうです。

PHP7.3から発生するようになったみたいなので、ちょっくら原因でも探ってみるかとソースを覗いてみたのですが、
7.3.0
7.2.24

諦めました。

ちなみにPHP7.0でコンパイルオプションpcre.jitというものが追加され、正規表現にJITを使うようになっています。
このJIT用メモリというのが意外と小さく、たとえば以下の正規表現はpcre.jitの状態によって返り値が変わってきます。

var_dump(preg_match('/^(A{1,2}B)+$/',str_repeat('AB',8192)));

pcre.jit=0であれば返り値は正しく1となります。
しかし、デフォルトのpcre.jit=1であれば返り値はfalseとなり、preg_last_errorにはJIT用メモリが足りないよというPREG_JIT_STACKLIMIT_ERRORが返ってきます。

でもpcre.jit=0にしても、最初の正規表現では2が返ってきました。
preg_last_errorを確認してもエラーは起こっていないので、pcre.jitは特に関係ないようです。

さてこのバグですが、先日修正されました
7.4にもマージされたので、2019/11/28リリース予定のPHP7.4.0正式版ではなおっていると思います。

なお、中身はifをひとつ突っ込んだだけで、どうしてこんなので直るのかさっぱりわかりません。


Viewing all articles
Browse latest Browse all 331

Trending Articles