Php 我的正则表达式有多糟?

Php 我的正则表达式有多糟?,php,regex,optimization,Php,Regex,Optimization,好吧,我用正则表达式解决了一个问题,但这个解决方案有点怪 要验证的字符串必须是: 零或更多:A-Z A-Z 0-9,空格或这些符号:-=+,:()/ 但是,第一个和/或最后一个字符不能是正斜杠/ 这是我的解决方案(使用preg_matchphp函数): 一位同事认为这太大太复杂了。好吧,它起作用了,那么它真的有那么糟糕吗?任何想玩regex高尔夫的人?您可以将您的表达简化为: /^(?:[a-z\d\s.\-=+',:()]+(?:/+[a-z\d\s.\-=+',:()]+)*)?$/i 外

好吧,我用正则表达式解决了一个问题,但这个解决方案有点怪

要验证的字符串必须是:

零或更多:
A-Z A-Z 0-9
,空格或这些符号:
-=+,:()/

但是,第一个和/或最后一个字符不能是正斜杠
/

这是我的解决方案(使用
preg_match
php函数):


一位同事认为这太大太复杂了。好吧,它起作用了,那么它真的有那么糟糕吗?任何想玩regex高尔夫的人?

您可以将您的表达简化为:

/^(?:[a-z\d\s.\-=+',:()]+(?:/+[a-z\d\s.\-=+',:()]+)*)?$/i
外部
(?:…)?
允许空字符串。
[a-z\d\s.\-=+',:()]+
允许以一个或多个指定字符开头,但
/
除外。如果后面跟着一个
/
,则它后面还必须跟一个或多个其他指定字符(
(?:/[a-z\d\s.\-=+',:())+)*


此外,在字符集中,您只需要转义字符
\
]
,并且根据位置也可以尝试类似的方法

function validate($string) {
   return (preg_match("/[a-zA-Z0-9.\-=+',:()/]*/", $string) && substr($string, 0,1) != '/' && substr($string, -1) != '/'))
}
具体检查第一个和最后一个字符要简单得多。否则,当涉及到空字符串之类的内容时,您将不得不处理大量开销。例如,您的正则表达式要求字符串至少有一个字符长,否则无法验证。尽管“符合您的标准。

”#^(?!/)[a-z\d=+\,:()/-]*$(?$variable
插值,但没有嵌入的可执行文件,
{code}
,您必须为它们转义的唯一字符是单引号和反斜杠

'#^(?!/)[a-z\d .=+\',:()/-]*$(?<!/)#i'

但是这里的主要创新是使用lookahead和lookahead来排除斜杠作为第一个或最后一个字符。这也不仅仅是一种代码高尔夫策略;无论如何,我都会以这种方式编写正则表达式,因为它更好地表达了我的意图。既然你可以说出你的意思?“……但第一个和最后一个字符不能是斜杠。”

我经常在代码中构建复杂的正则表达式字符串,这样我就可以使用注释和添加缩进。否则,我有0.0001%的机会在以后编辑这些怪物。好吧,正则表达式总是这样,第一个人会在一周后忘了它是如何工作的,如果有人看到你的代码,他会觉得有挑战性地去做一个较小的正则表达式,可能会失败,所以这里的问题是lookbehing是非消耗性的。因此,虽然它将检查第一个字符是否为/,character类将允许斜杠作为第一个字符,我相当确定这可能是个问题。如果第一个字符是斜杠,则lookbehind将失败,而regex将在不应用字符类的情况下失败。这与重新安排解决方案以放置
substr($string,0,1)是一样的首先,如果该部分失败,将永远不会调用
preg\u match
和另一个
substr
。感谢此解决方案:使用
向后查看
来检查下一个字符,而不是像
那样的
向前看
。^(?!/)[a-z\d.=+\,:()/-*(?!/)$#i'
。在
$
之后的
向后看的位置也很重要吗?@Julien:它不必在
$
之后,但它必须是向后看,而不是向前看。
(意思是“我在字符串末尾,最后一个字符不是斜杠”(顺序不重要,因为它们都是零宽度断言)。
(?!/)$
的意思是“我在字符串末尾,下一个字符不是斜杠”——当然不是:没有下一个字符!(完全公开:
$
也可以在字符串末尾的换行符之前进行匹配。如果目标字符串可能以换行符结尾,则应使用
\z
。)我喜欢这个想法,但1)必须在[]内转义/2)$string-likeab@c将进行验证,因为您未使用^nor$3)顺便说一句,您的最后一次结算)应为a;
'#^(?!/)[a-z\d .=+\',:()/-]*$(?<!/)#i'