提问者:小点点

为什么我的regexp误解了模式的结尾?[副本]


我尝试为SQLorderby子句实现一个验证器,我有一个表达式

$expression = '/^(([a-z]|[A-Z]|[0-9]|\.|_)+([\s])+([desc|asc]){1})/i'

如果我们检查preg_match($表达式,$value),那么它可以正常工作。现在,我想确保值以ascdesc结束。但是

$expression = '/^(([a-z]|[A-Z]|[0-9]|\.|_)+([\s])+([desc|asc]){1}$)/i'

对于abc4a ASC“4abc4\n\r desc”失败。没有$的同一表达式认为它们有效。为什么字符串以descasc结尾,我的正则表达式发现它们无效,除非我删除$符号?


共1个答案

匿名用户

[…]在正则表达式中称为字符类。它匹配一个字符,该类中的任何字符。这意味着[asc]匹配一个asc,但只匹配一个字符,而不是整个字符串asc

片段[desc | asc]匹配descasc中的一个字符。它相当于[acdes |](字符类中的字符可以按任何顺序列出,重复的字符将被忽略)。

您的正则表达式应该是:

$expression = '/^(([a-z]|[A-Z]|[0-9]|\.|_)+([\s])+(desc|asc){1}$)/i'

它可以被简化和修正<代码>{1}是多余的。这意味着前一个片段只出现一次,但这是默认值<代码>{1}始终可以删除。

[a-z]|[a-z]表示ab列表中的一个字符z(小写字符)或aBZ(大写字符)。两个范围(以及在正则表达式中可能出现在该位置的其他范围和字符)都可以组合成一个类:[a-zA-Z0-9.\uz]

[\s]是指\s中的一种,它可能不是您想要的。您可能需要一个或多个空格字符(\s是表示空格字符的特殊序列)。

除了desc|asc周围的括号之外,不需要括号(除非您想捕获匹配的字符串)。

总之,您的正则表达式应该是:

$expression = '/^[a-zA-Z0-9._]+\s+(desc|asc)$/i';