Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
5
Help us understand the problem. What is going on with this article?
@sola-msr

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

More than 1 year has passed since last update.

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

5
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  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
sola-msr
ミセ*゚ー゚)リ そんな事言われてもウチ、ポン・デ・ライオンやし
andfactory
Smartphone Idea Companyとして、人々の生活に「&(アンド)」を届ける。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
5
Help us understand the problem. What is going on with this article?