我使用Laravel作为我的框架,并且我尝试使用自己的preg_match函数来验证表单。
以下是我的代码:
Validator::extend('alpha_num_spaces', function ($attribute, $value)
{
return preg_match('/^([-a-z0-9_-\s])+$/i', $value);
});
现在,我已经在生产服务器上运行它,但它在我收到的本地计算机上运行正常:
preg_match(): Compilation failed: invalid range in character class at offset 13
我的猜测与PHP版本的差异有关?但我完全基于这个猜测。或者也许正则表达式存在一些错误?
提前致谢。
答案 0 :(得分:5)
“我的猜测与PHP版本的差异有关”。实际上,我认为生产服务器的版本将\s
视为文字s
并忽略反斜杠。 (当然,测试带有空格的字符串)。但是你的测试服务器会看到一个字符和一个速记字符类之间的范围,这显然没有任何意义。
最近版本的PCRE足够聪明(当它是明确的时候),当一个连字符前面有一个速记字符类或一个范围时,它不会定义一个字符范围。例如:[\s-ABC]
或[0-9-ABC]
是正确的。(在这些情况下,您无需转义)
结论,你可以写:
[-a-z0-9_\s]
[a-z0-9_\s-]
[a-z0-9-_\s]
[a-z-0-9_\s]
[a-z0-9\s-_]
[a-z0-9_\-\s]
但不是:
[a-z0-9_-\s]
答案 1 :(得分:4)
您需要使用:
preg_match('/^([-a-z0-9_\s])+$/i', $value);
OR
preg_match('/^([-\w\s])+$/i', $value);
你的角色类中间有一个未转义的连字符。
连字符需要在角色类的第一个或最后一个位置或者它应该被转义。此外,你已经在第一个地方有一个连字符,所以不需要再次使用连字符。
答案 2 :(得分:2)
连字符必须是最后一个字符,如果您希望它是匹配的字符之一:
return preg_match('/^([-a-z0-9_\s-])+$/i', $value);