Preg_match() : 编译失败: 字符类中的偏移量范围无效

预先感谢您的时间,帮助这个问题. 。

Preg _ match () : 编译失败: 第278行偏移量为20session.php 的字符类中的范围无效

在我们的服务器上进行了 PHP 升级之后,经过几个月的工作之后,这个程序突然停止了工作。

这是密码

    else{
/* Spruce up username, check length */
$subuser = stripslashes($subuser);
if(strlen($subuser) < $config['min_user_chars']){
$form->setError($field, "* Username below ".$config['min_user_chars']."characters");
}
else if(strlen($subuser) > $config['max_user_chars']){
$form->setError($field, "* Username above ".$config['max_user_chars']."characters");
}




/* Check if username is not alphanumeric */
/* PREG_MATCH CODE */


else if(!preg_match("/^[a-z0-9]([0-9a-z_-\s])+$/i", $subuser)){
$form->setError($field, "* Username not alphanumeric");
}




/* PREG_MATCH CODE */




/* Check if username is reserved */
else if(strcasecmp($subuser, GUEST_NAME) == 0){
$form->setError($field, "* Username reserved word");
}
/* Check if username is already in use */
else if($database->usernameTaken($subuser)){
$form->setError($field, "* Username already in use");
}
/* Check if username is banned */
else if($database->usernameBanned($subuser)){
$form->setError($field, "* Username banned");
}
}
108401 次浏览

字符类范围是通过在字符类中的两个值之间使用-来定义的(正则表达式中为 [])。[0-9]意味着0到9之间的一切,包括。在代码中的正则表达式中,有几个字符类范围 a-z0-9。还有一个类,你可能不想放在那里,即 _-\s

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

在某些情况下(大多数情况下?) ,这并不被认为是无效的字符范围PCRE 的版本(PHP 使用的正则表达式库) ,但它最近可能发生了变化,如果 PCRE 库在服务器上升级,这可能就是原因。

Debuggex 是一个很好的工具,它可以帮助调试错误(好吧,来自 PHP 的错误消息告诉了 还有行错误所在的字符,所以。.)像这样(我不是附属的,只是一个球迷)。

您的错误取决于您的正则表达式解释器。

可以转义连字符以清楚它的用法

你的最终密码:

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

这个问题确实很老了,但是还有一些与 PHP 7.3和更新版本相关的新发展需要讨论。而 PHP 7.3中使用的 PCRElibrary 版本是10.32,这就是 向后不兼容的更改的起源:

  • 内部库 API 已更改
  • “ S”修饰符没有效果,模式是自动学习的。没有真正的影响。
  • “ X”修饰符是 PCRE2中的默认行为。当前的补丁将行为还原为 PCRE 中“ X”的含义,但是最好使用新的行为并在默认情况下打开“ X”。所以目前也没有影响。
  • 由于更新的 Unicode 引擎,出现了一些行为变化。PCRE2中的 Unicode 10对 PCRE 中的 Unicode 7。一些行为变化可以通过无效的模式看到。

根据 PHP 10.33更新日志:

  1. 设置 PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL时,转义序列如 \s 它们在字符类中有效,但不作为范围的末尾 一个例子是 [_-\s](但不是 [\s-_],因为它给出了一个 现在给出了一个“无效范围”错误 独立于 PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL

在 PHP 7.3之前,如果转义了连字符,或者将其放在 “在一个不能被解释为指示范围的位置”中,可以在任何位置使用连字符。在 PHP 7.3中,PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL似乎被设置为 false。因此,从现在开始,为了把连字符放入一个字符类,始终只在开始或结束位置使用它

另见 这个参考:

简而言之,

PCRE2在模式验证方面更加严格,因此在升级之后,一些现有的模式无法再进行编译。

下面是 php.net 中使用的简单代码片段

preg_match('/[\w-.]+/', ''); // this will not work in PHP7.3
preg_match('/[\w\-.]+/', ''); // the hyphen need to be escaped

正如您可以从上面的示例中看到的,这两行之间有一点但实质性的区别。

我有一个错误,我通过这样做来解决它

Route::get('{path}','HomeController@index')->where( 'path', '([A-z]+)?' );

这是我的工作。

也许这个答案可以拯救阿拉伯/波斯鼻涕虫的创造者:

对于 php 版本是 7.3,使用 \-代替 -

[ ^ a-z0-9 _ s-

还有

“/[ s-_ ] +/”

因此,对于 php 7.3的阿拉伯语 make _ slug 函数:

function make_slug($string, $separator = '-')
{
$string = trim($string);
$string = mb_strtolower($string, 'UTF-8');


// Make alphanumeric (removes all other characters)
// this makes the string safe especially when used as a part of a URL
// this keeps latin characters and Persian characters as well
$string = preg_replace("/[^a-z0-9_\s\-ءاآؤئبپتثجچحخدذرزژسشصضطظعغفقكکگلمنوهی]/u", '', $string);


// Remove multiple dashes or whitespaces or underscores
$string = preg_replace("/[\s\-_]+/", ' ', $string);


// Convert whitespaces and underscore to the given separator
$string = preg_replace("/[\s_]/", $separator, $string);


return $string;
}