正则表达式中()和[]之间的区别是什么?

时间:2009-10-28 05:35:01

标签: regex

让我们说:

/(a|b)/ vs /[ab]/

3 个答案:

答案 0 :(得分:19)

您的上述示例(在大多数语言中)没有太大区别。主要区别在于()版本会创建一个可以在匹配中由\1反向引用的组(有时候,$1)。 []版本不会这样做。

此外,

/(ab|cd)/  # matches 'ab' or 'cd'
/[abcd]/   # matches 'a', 'b', 'c' or 'd'

答案 1 :(得分:7)

正则表达式中的

()用于对正则表达式进行分组,允许您将运算符应用于整个表达式而不是单个字符。例如,如果我有正则表达式ab,则ab*引用a后跟任意数量的b s(例如,aababb等),而(ab)*指的是序列ab的任意数量的重复(例如,空字符串,ab,{ {1}}等)。在许多正则表达式引擎中,abab也用于创建匹配后可引用的引用。例如,在Ruby中,执行()后,"foo" =~ /f(o*)/将包含$1

正则表达式中的

oo表示交替;它表示条形图之前的表达式或它之后的表达式。您可以将任何数字与表达式|匹配。为了分组或捕获子表达式,您经常会看到包含在一组括号中的替换,但这不是必需的。您也可以在较长的表达式上使用替换,例如0|1|2|3|4|5|6|7|8|9,以指示foo|barfoo

你可以表达每个正则表达式(在正式的,理论上的意义上,而不是许多语言使用的扩展意义),只需要交替bar,kleene closure |,连接(只写两个表达式)彼此相邻,两者之间没有任何内容),以及用于分组的括号。但是对于复杂的表达式来说这是相当不方便的,因此通常可以使用几个简写。例如,*只是x?的简写(即空字符串或|x),而xy+的简写。< / p>

yy*基本上是其中所有字符或字符范围的交替[]的简写。正如我所说,我可以写|,但写0|1|3|4|5|6|7|8|9会更方便。我也可以写[0-9]代表任何一封信。请注意,尽管[a-zA-Z]确实提供了分组,但它们通常不会引入可在以后引用的新引用;你必须将它们包装在括号中,如[]

因此,您的两个示例正则表达式在它们匹配的内容中是等效的,但([a-zA-Z])将第一个子匹配设置为匹配字符,而(a|b)将不会创建对子匹配的任何引用匹配。

答案 2 :(得分:6)

首先,在谈论正则表达式时,指定您正在谈论的正则表达式通常很重要。有几种变体(例如传统的POSIX正则表达式,Perl和Perl兼容的正则表达式(PCRE)等)。

假设PCRE或其他非常相似的东西,这些天常常见,这有三个主要区别:

  1. 使用括号组,您可以检查包含多个字符的选项。所以/(a | b)/可能改为/(abc | defg)/。
  2. 括号组执行捕获操作,以便您可以提取结果(如果匹配“b”,则可以返回“b”并查看)。 / [ab] /没有。可以通过添加?:覆盖捕获操作:如:/(?:a | b)/
  3. 即使你覆盖括号的捕获行为,当你检查单个字符时,[]的底层实现可能仍然会更快(尽管没有任何说明非捕获(?:a | b)无法优化为[ab]中的特殊情况,但正则表达式编译可能会花费更长的时间。)