Pet*_*ter 19

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

也,

/(ab|cd)/  # matches 'ab' or 'cd'
/[abcd]/   # matches 'a', 'b', 'c' or 'd'
Run Code Online (Sandbox Code Playgroud)

  • 不,这是一个重点 - 事实上,这是我使用`(a | b)`而不是`[ab]`的主要原因. (3认同)
  • ()也用于表示命名组,以便重用 (2认同)

Bri*_*ell 7

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

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

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

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

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


Nic*_*ght 6

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

假设PCRE或类似的东西(这些日子通常是最常见的),有三个主要区别:

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