对于PCRE正则表达式,[abc]和(a | b | c)之间有什么区别?
答案 0 :(得分:10)
问题中的模式与相同的文字相匹配。在实现方面,它们对应于不同的自动机和副作用(即,无论它们是否捕获子串)。
在下面的评论中,Garrett Albright指出了一个微妙的区别。 (.|\n)
匹配任何字符,[.\n]
匹配文字点或换行符。虽然点在字符类中不再是特殊的,但-
,^
和]
等其他字符以及[:lower:]
等序列在字符类中具有特殊含义。需要注意保持从一个上下文到另一个上下文的特殊语义,但有时候不可能在\1
的情况下作为在字符类之外编写$1
的古老方式。在角色类中,\1
始终与角色SOH匹配。
字符类([...]
)经过优化,可以匹配某些字符集中的一个字符,而备选字符(x|y
)允许更多长度的更一般选择。如果您牢记这些设计原则,您将倾向于看到更好的性能。正则表达式实现将/[abc]/
等源代码转换为有限状态自动机,通常为NFAs。我们认为正则表达式引擎是或多或少的帮助执行这些目标状态机的簿记员。足够聪明的正则表达式编译器将为等效的正则表达式生成相同的机器代码,但由于lurking exponential complexity,这在一般情况下是困难且昂贵的。
有关正则表达式背后理论的可访问介绍,请阅读Mark Dominus撰写的“How Regexes Work”。如需深入研究,请考虑Peter Linz的An Introduction to Formal Languages and Automata。
答案 1 :(得分:1)
(在阅读Greg的答案之后):如果他们的评价方式不同,则应该依赖于他们提供的任何程序。选择您要检查的内容。您想要检查有效字符池,还是要检查值? - 有时看起来可能相同,但它背后可能有不同的意图。然后选择反映您意图的内容。
答案 2 :(得分:0)
使用方括号的表单在PCRE上要快得多,尤其是在启用JIT编译的情况下。它只是在bitset中检查一下,而另一个则为每个替代品重新读取该字符。我正在考虑一种可以检测这种情况的优化,因为很多人不知道在方括号内可以使用字符类,并且它们使用([az] | \ s)+而不是[az \ s] +。