2012-05-21 142 views
2

对于PCRE正则表达式,[abc]和(a | b | c)有什么区别?[abc]和(a | b | c)之间的区别

+3

相关[使用交替或字符类的单个字符匹配?](http://stackoverflow.com/questions/4724588/using-alternation-or-character-class-for-single-character-matching)有一些有趣的答案。 – stema

+0

那个帖子很有帮助。谢谢 – user1032531

回答

8

问题中的模式匹配相同的文本。在实施方面,它们对应于不同的自动机和副作用(,即,它们是否捕获子串)。

在下面的评论中,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

+0

你什么时候使用一个? “他们对应不同的自动机和子串捕获”是什么意思?谢谢 – user1032531

+0

如果a,b和c只是字母,当然(就像我认为的意思)。如果他们能够代表文字,显然它是完全不同的语义。 – kratenko

+0

我发现有时方括号选项似乎不适合有趣的字符,如'\ n'或'\ r'。例如,要捕捉包含换行符的FOO和BAR之间的所有文本,'/ FOO((。| \ n)+)BAR /'有效,而'/ FOO([。\ n] +)BAR /'没有。不过,这可能是特定于实现的。我发现了其他的差异,就像我无法回想起我的头顶。无论如何,一般来说,我会先尝试使用'[ab]',因为它更具可读性,如果事情似乎没有奏效,那就试试'(a | b)'。 –

1

(阅读格雷格的回答后):如果他们有不同的评价应该依赖于你给他们的任何程序。选择你想要检查的内容。你想检查一堆有效的字符,或者你想检查值。 - 有时看起来可能是一样的,但它背后可能有不同的意图。然后选择反映你意图的东西。

0

PCRE使用方括号的表格要快得多,特别是在启用了JIT编译的情况下。它只是在比特中检查一下,而另一个重新读取每个选择的字符。我正在考虑一种可以检测这种情况的优化,因为很多人不知道可以在方括号内使用字符类,并且它们使用([a-z] | \ s)+而不是[a-z \ s] +。

相关问题