1. rana_kualu

    Posted

    rana_kualu
Changes in title
+preg_matchが2を返す
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,48 @@
+# https://bugs.php.net/bug.php?id=78853
+
+
+[preg_match](https://www.php.net/manual/ja/function.preg-match.php)は、パターンにマッチした場合は1を、マッチしなければ0を、エラーが発生したらfalseを返します。
+
+![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/9894f7a5-617f-5e43-0d63-3b07558193c0.png)
+
+ということでこんな正規表現を試してみましょう。
+
+```php
+var_dump(preg_match('/^|\d{1,2}$/', "7"));
+```
+
+[結果](https://3v4l.org/m49BV)
+
+![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/2d4b0286-aa7e-b8f0-4402-3ae777028a98.png)
+
+なんだこれ?
+
+2が返ってきました。
+[英語版](https://www.php.net/manual/en/function.preg-match.php)にもしっかり"1か0かfalseを返す"と書いてあって、ドキュメントの更新漏れとかでもなさそうです。
+
+PHP7.3から発生するようになったみたいなので、ちょっくら原因でも探ってみるかとソースを覗いてみたのですが、
+[7.3.0](https://github.com/php/php-src/blob/php-7.3.0/ext/pcre/php_pcre.c#L988)
+[7.2.24](https://github.com/php/php-src/blob/php-7.2.24/ext/pcre/php_pcre.c#L742)
+
+諦めました。
+
+
+ちなみにPHP7.0でコンパイルオプション`pcre.jit`というものが追加され、[正規表現にJITを使う](https://qiita.com/ryosukes/items/3f526ff0dd3fc4f9c3b5)ようになっています。
+このJIT用メモリというのが意外と小さく、たとえば以下の正規表現は`pcre.jit`の状態によって返り値が変わってきます。
+
+```php
+var_dump(preg_match('/^(A{1,2}B)+$/',str_repeat('AB',8192)));
+```
+
+`pcre.jit=0`であれば返り値は正しく1となります。
+しかし、デフォルトの`pcre.jit=1`であれば返り値はfalseとなり、[preg_last_error](https://www.php.net/manual/ja/function.preg-last-error.php)にはJIT用メモリが足りないよという[PREG_JIT_STACKLIMIT_ERROR](https://www.php.net/manual/ja/pcre.constants.php)が返ってきます。
+
+
+でも`pcre.jit=0`にしても、最初の正規表現では2が返ってきました。
+preg_last_errorを確認してもエラーは起こっていないので、`pcre.jit`は特に関係ないようです。
+
+
+さてこのバグですが、先日[修正されました](http://git.php.net/?p=php-src.git;a=commit;h=e1da72bdf18aa3d413c5324bccfd8dc521c217e3)。
+[7.4にもマージされた](https://github.com/php/php-src/commit/cfb643ca2b1e03d0211b5bf089560c1dd3a41359)ので、2019/11/28リリース予定のPHP7.4.0正式版ではなおっていると思います。
+
+なお、中身は[ifをひとつ突っ込んだだけ](https://github.com/php/php-src/commit/e1da72bdf18aa3d413c5324bccfd8dc521c217e3)で、どうしてこんなので直るのかさっぱりわかりません。