我的正则表达有多糟糕?

时间:2010-09-30 10:38:31

标签: php regex optimization

好的,所以我设法用正则表达式来解决问题,但解决方案有点像怪物。

要验证的字符串必须是:

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

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

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

"/^[a-z\d\s\.\-=\+\',:\(\)][a-z\d\s\.\-=\+\',\/:\(\)]*[a-z\d\s\.\-=\+\',:\(\)]$|^[a-z\d\s\.\-=\+\',:\(\)]$/i"

一位同事认为这太大而复杂。它有效,所以真的那么糟糕吗?有人想要一些正则表达式高尔夫吗?

3 个答案:

答案 0 :(得分:4)

您可以将表达式简化为:

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

外部(?:…)?是允许空字符串。 [a-z\d\s.\-=+',:()]+允许以/以外的一个或多个指定字符开头。如果跟随/,则必须后跟一个或多个其他指定字符((?:/[a-z\d\s.\-=+',:()]+)*)。

此外,在字符集中,您只需要转义字符\],并根据位置^-转义。

答案 1 :(得分:2)

尝试这样的事情

function validate($string) {
   return (preg_match("/[a-zA-Z0-9.\-=+',:()/]*/", $string) && substr($string, 0,1) != '/' && substr($string, -1) != '/'))
}

特别检查第一个和最后一个字符要简单得多。否则,当谈到空字符串等时,你就会面临很多开销。例如,你的正则表达式要求字符串至少有一个字符长,否则它不会验证。尽管“符合你的标准。”

答案 2 :(得分:2)

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

正如其他人所观察到的那样,大多数这些角色不需要在角色类中进行转义。另外,如果连字符是最后列出的内容,则不需要对连字符进行转义,如果使用不同的字符作为正则表达式分隔符(在这种情况下为#),则不需要转义斜杠,但{ {1}}也是一个受欢迎的选择。

我也抛弃了双引号而支持单引号,这意味着我必须逃避正则表达式中的单引号。这是值得的,因为单引号字符串使用起来非常简单:没有~插值,没有嵌入式可执行文件$variable,并且您必须为它们转义的唯一字符是单引号和反斜杠。

但这里的主要创新是使用前瞻和后瞻来将斜线排除为第一个或最后一个角色。这也不仅仅是代码高尔夫战术;无论如何我会以这种方式编写正则表达式,因为它表达了我的意图更好。当你能说出你的意思时,为什么强迫下一个人解析那几乎相同的角色类? “......但是第一个和最后一个字符不能是斜线。”