提前感谢您抽出时间帮助解决这个问题。
preg_match():编译失败:第278行偏移20 session.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");
}
}
答案 0 :(得分:20)
字符类范围是使用 - 在字符类中的两个值(正则表达式中为[]
)之间定义的。 [0-9]
表示0到9之间的所有内容,包括0和9。在代码中的正则表达式中,您有多个字符类范围a-z
,0-9
。还有一个类你可能并不想放在那里,即_-\s
。
"/^[a-z0-9]([0-9a-z_-\s])+$/i"
^^^^
在某些(大多数?)版本的PCRE(PHP使用的正则表达式库)中,这显然不被视为无效字符范围,但最近可能已更改,如果PCRE库已在服务器上升级,则可能是原因。
Debuggex是一个很好的工具,可以帮助调试错误(好吧,PHP的错误消息告诉你行和错误所在的字符,所以..)像这(我不是附属的,只是一个粉丝)。
答案 1 :(得分:4)
您的错误取决于您的正则表达式解释器。
您可以转义连字符以明确其用途。表示使用\-
代替-
。
您的最终代码:
/^[a-z0-9]([0-9a-z_\-\s])+$/i
答案 2 :(得分:1)
也许这个答案可以拯救阿拉伯/波斯语Slug创作:
对于 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;
}
答案 3 :(得分:0)
这个问题确实很老,但是有一些涉及PHP 7.3的新开发和较新的版本需要涵盖。 PHP PCRE引擎迁移到PCRE2 ,这就是Backward Incompatible Changes的来源:
- 内部库API已更改
- 'S'修饰符无效,系统会自动研究模式。没有实际影响。
- “ X”修饰符是PCRE2中的默认行为。当前补丁将行为恢复为PCRE中的“ X”含义,但最好采用新行为并默认情况下启用“ X”。所以目前也没有影响。
- 已发现由于更新的Unicode引擎而导致的某些行为更改。 PCRE2中为Unicode 10,而PCRE中为Unicode 7。某些行为改变可以通过无效的模式看到。
在PHP 7.3之前,如果逃脱了连字符或将其放在"in a position where it cannot be interpreted as indicating a range"中,则可以在字符类的任何位置使用连字符。现在,为了将连字符放入字符类中,总是只在开始或结束位置使用它。
另请参阅此参考文献:
简单来说,
PCRE2在模式验证方面更加严格,因此升级后,您现有的某些模式将无法再编译。
这是php.net中使用的简单代码段
preg_match('/[\w-.]+/', ''); // this will not work in PHP7.3 preg_match('/[\w\-.]+/', ''); // the hyphen need to be escaped从上面的示例中可以看到,两行之间有一点点但实质性的区别。
答案 4 :(得分:0)
我遇到此错误,我通过执行此操作来解决
Route::get('{path}','HomeController@index')->where( 'path', '([A-z]+)?' );
这对我有用。
答案 5 :(得分:0)
我在Larave路线中遇到了同样的错误,我这样解决。
Route::get('/{any}', 'SpaController@index')->where('any', '.*');
答案 6 :(得分:-2)
首先, 路线:: get('{path}',“ HomeController @ index”)-> where('path','([[A-z \ d-/ _。] +)?');
当我从下面尝试并发生时,它对我不起作用:-)
Route :: get('{path}','HomeController @ index')-> where('path','([[A-z] +)?')