对于 PCRE 正则表达式,[abc] 和 (a|b|c) 有什么区别?
(.| \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。
\n
或\r
这样的特殊字符似乎无法正常工作。例如,要捕获包括换行符在内的FOO和BAR之间的所有文本,/FOO((.|\n)+)BAR/
有效,而/FOO([.\n]+)BAR/
则无效。虽然这可能是实现特定的,但我发现了其他类似的差异,但我无法立即回忆起来。无论如何,作为一个规则,我会首先尝试使用[ab]
,因为它更易读,如果事情似乎不起作用,那么再尝试(a|b)
。 - Garrett Albright