Help us understand the problem. What is going on with this article?

preg_matchが2を返す

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

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

01.png

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

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

結果

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をひとつ突っ込んだだけで、どうしてこんなので直るのかさっぱりわかりません。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away