让我们说:
/(a|b)/
vs /[ab]/
答案 0 :(得分:19)
您的上述示例(在大多数语言中)没有太大区别。主要区别在于()
版本会创建一个可以在匹配中由\1
反向引用的组(有时候,$1
)。 []
版本不会这样做。
此外,
/(ab|cd)/ # matches 'ab' or 'cd'
/[abcd]/ # matches 'a', 'b', 'c' or 'd'
答案 1 :(得分:7)
()
用于对正则表达式进行分组,允许您将运算符应用于整个表达式而不是单个字符。例如,如果我有正则表达式ab
,则ab*
引用a
后跟任意数量的b
s(例如,a
, ab
,abb
等),而(ab)*
指的是序列ab
的任意数量的重复(例如,空字符串,ab
,{ {1}}等)。在许多正则表达式引擎中,abab
也用于创建匹配后可引用的引用。例如,在Ruby中,执行()
后,"foo" =~ /f(o*)/
将包含$1
。
oo
表示交替;它表示条形图之前的表达式或它之后的表达式。您可以将任何数字与表达式|
匹配。为了分组或捕获子表达式,您经常会看到包含在一组括号中的替换,但这不是必需的。您也可以在较长的表达式上使用替换,例如0|1|2|3|4|5|6|7|8|9
,以指示foo|bar
或foo
。
你可以表达每个正则表达式(在正式的,理论上的意义上,而不是许多语言使用的扩展意义),只需要交替bar
,kleene closure |
,连接(只写两个表达式)彼此相邻,两者之间没有任何内容),以及用于分组的括号。但是对于复杂的表达式来说这是相当不方便的,因此通常可以使用几个简写。例如,*
只是x?
的简写(即空字符串或|x
),而x
是y+
的简写。< / 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或其他非常相似的东西,这些天常常见,这有三个主要区别: