LoginSignup
11
7

More than 5 years have passed since last update.

【PHP】preg_match()関数を用いた正規表現のマッチングの挙動が7.2系から7.3系で変わってる(PCREのバージョン変更)

Last updated at Posted at 2019-04-25

preg_match()関数でエラーがでた

何気なくローカルの開発環境でLaravel用Homesteadのバージョンをあげて、過去のプロジェクトのテスト(PHPUnit)を走らせてみた際、
いままで出てなかったエラーが発生。

preg_match(): Compilation failed: invalid range in character class at offset **

発生個所的にバリデーションのテストを書いてるところで、正規表現のルールでエラーがでてるっぽい。
なんでいきなり??ってことで調査開始

PHP7.2系(7.1系)とPHP7.3系の挙動

簡単な半角英数字とハイフンを通す正規表現の処理を書いてみました。

<?php
$str = 'RANDOMWORD-123';
var_dump(preg_match('/^[a-zA-Z0-9\s--]+$/', $str));

以下がPHP7.1系PHP7.3系の結果


FireShot Capture 013 - Online PHP editor - output for 42BcG - 3v4l.org.png
https://3v4l.org/42BcG


んーなんで??バージョン上げたからってそんなにクリティカルなエラーが出るようになるもんなの・・・?
って思いながらググるとStack Overflowでこたえっぽいの発見

php - preg_match(): Compilation failed: invalid range in character class at offset 20 - Stack Overflow

A character class range is defined by using - between two values in a character class ([] in regex). [0-9] means everything between 0 and 9, inclusive. In the regular expression in your code, you have several character class ranges, a-z, 0-9. There is also one class that you probably didn't mean to put there, namely _-\s.

"/^[a-z0-9]([0-9a-z_-\s])+$/i"
                   ^^^^ 

This is apprently not considered an invalid character range in some (most?) versions of PCRE (the regular expression library PHP uses), but it might have changed recently, and if the PCRE library was upgraded on the server, that might be the reason.

以下部分Google翻訳

PCRE(PHPが使用する正規表現ライブラリ)のバージョンですが、最近変更された可能性があります。PCREライブラリがサーバー上でアップグレードされた場合は、それが理由である可能性があります。

らしいです。
どうやらPHP7.3系からなので

PCRE:
Implemented https://wiki.php.net/rfc/pcre2-migration.
Upgrade PCRE2 to 10.32.
Fixed bug #75355 (preg_quote() does not quote # control character).
Fixed bug #76512 (\w no longer includes unicode characters).
Fixed bug #76514 (Regression in preg_match makes it fail with PREG_JIT_STACKLIMIT_ERROR).
Fixed bug #76909 (preg_match difference between 7.3 and < 7.3).

このあたりの修正・更新対応が入ったからなんですかね・・・?

エラーが発生しないように正規表現の書き方を修正

とにかくStack Overflowで指摘されているようにハイフン(-)が原因みたいなので位置を変えてみます

<?php
$str = 'RANDOMWORD-123';
var_dump(preg_match('/^[a-zA-Z0-9\s--]+$/', $str)); // ハイフン(-)の位置を変えた

以下PHP7.1(7.1.25)PHP7.3(7.2.17)での実行結果


FireShot Capture 010 - Online PHP editor - output for RAoU5 - 3v4l.org.png
https://3v4l.org/hCfWq


エラーがでなくなりました

おわり

  • 原因がわりとわからなかった
  • 詳しい人詳細を教えてください。。。

参考URL

11
7
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
7