正则表达式中的“+”符号是什么意思?

50

正则表达式中的加号符号代表什么意思?


你能否请发一份样例? - kennytm
14
/s+a+m+p+l+e+/ - Déjà vu
4
这句话的意思是“^^可以匹配'sample'、'samplee'和'sssaaaaaammmppplllllle',但不能匹配'smple'”。 - rolling_codes
5个回答

80
"

+在不同的上下文中有两种不同的含义。

像其他答案提到的那样,+通常是一个重复运算符,会导致前面的标记重复一次或多次。在形式语言理论中,a+可以表示为aa*,也可以表示为a{1,}(匹配至少1次和最多无限次)。

"
然而,如果+跟随重复运算符(即?+*+++{m,n}+),它也可以使其他量词possessive。占有量词是一些正则表达式引擎(PCRE、Java和JGsoft引擎)的高级功能,告诉引擎在匹配成功后不要回溯。
为了理解这个过程,我们需要了解正则表达式引擎的两个概念:贪婪性和回溯。贪婪性通常意味着正则表达式将尝试尽可能多地消耗字符。假设我们的模式是.*dot是正则表达式中的特殊构造,表示任何字符1;星号表示匹配零次或多次),目标是aaaaaaaab。整个字符串将被消耗,因为整个字符串是满足模式的最长匹配。
然而,假设我们将模式更改为.*b。现在,当正则表达式引擎尝试匹配aaaaaaaab时,.*将再次消耗整个字符串。但是,由于引擎已经到达了字符串的末尾,并且模式尚未满足(.*消耗了除b之外的所有内容,但模式仍然必须匹配b),因此它会回溯,一次一个字符地尝试匹配b。第一次回溯将使.*消耗aaaaaaaa,然后b可以消耗b,模式成功。
占有量词也是贪婪的,但是如上所述,一旦它们返回匹配项,引擎就无法回溯到该点之前。因此,如果我们将模式更改为.*+b(匹配任意字符零次或多次,具有占有性质,后跟b),并尝试匹配aaaaaaaab,同样,.*将消耗整个字符串,但是由于它是占有性质的,回溯信息被丢弃,因此无法匹配b,模式失败。

1 在大多数引擎中,点号不会匹配换行符,除非指定了/s("singleline"或"dotall")modifier修饰符。


+1;所有格量词只在Java、PCRE或JGSoft正则表达式引擎中有效。而Ruby、Perl和.NET使用原子组(?>.*) - Tim Pietzcker
@Tim,我之前提到过这个问题,但现在我在我的回答中更加明确地表达了出来。 - Daniel Vandersluis
@Tim:Perl 支持贪婪量词,可能自 5.10 版本开始。 - ninjalj
@ninjalj:谢谢你提供的信息。看起来这个比较已经不再更新了。 - Tim Pietzcker
太棒了!真的帮助我理解了很多。谢谢你。 - realnsleo

21
在大多数实现中,+ 表示“一个或多个”。
在一些理论著作中,+ 被用来表示“或”(大多数实现使用|符号表示)。

11

1 或多个前面的表达式。

[0-9]+

将匹配:

1234567890

在以下文本中匹配:

我有1234567890美元


6

前一个符号出现一次或者多次。

例如,a+表示字母a出现一次或者多次。因此,a可以匹配aaaaaaaaa但不能匹配空字符串。

如果您知道星号(*)的含义,则可以将(exp)+表示为(exp)(exp)*,其中(exp)是任何正则表达式。


2
很多情况取决于加号符号出现的位置和正则表达式的类型。
在 posix-bre 和 vim(非非常魔术模式)的表达式中,加号匹配一个文本字符“+”。例如,sed 's/+//g' file > newfile 将删除 file 中的所有加号字符。如果要在此处将加号用作定量器,请使用“\+”(在 GNU 工具中受支持),或替换为“{1,}”或将定量器从第一部分中删除,并在另一部分后添加“*”(零个或多个出现定量器),例如:sed 's/c++*//' 会删除一个c后面跟着一个或多个加号字符。
在 posix-ere 和其他正则表达式风格中,在字符类([...])之外,加号充当一个定量器,意思是“一个或多个,但尽可能多地出现定量化模式”。例如,在 javascript 中,s.replace(/\++/g, '-') 会将像++++这样的字符串替换为单个的“-”。请注意,在 NFA 正则表达式风格中,加号有一个惰性对应项“+?”,它匹配“一个或多个,但尽可能少地出现定量化模式”。
在字符类中,无论在哪种正则表达式语言中,+字符都被视为字面字符。 [+]总是匹配单个+字面字符。例如,在中,Regex.Replace("1+2=3", @"[+]", "-")将导致1-2=3。请注意,在字符类中使用单个字符不是一个好主意,只有在需要两个或更多字符或字符集时才使用字符类。例如,[+0-9]匹配一个+或任何ASCII数字字符。在中,preg_replace('~[\s+]+~', '-', '1 2+++3')将导致1-2-3,因为正则表达式匹配一个或多个(由于最后一个+是量词符号)空格(\s)或加号字符(字符类内的+)。 +符号也可以是一些PCRE类正则表达式(如possessive quantifier)的一部分,例如等(但不包括 re)。例如,在 PCRE中,C\+++(?!\d)将匹配C,然后是一个或多个+符号(\+表示一个字面上的+++表示允许回溯到此量化模式中的一个或多个出现),但不跟在数字后面。如果加号字符后面有数字,则整个匹配失败。其他例子:a?+(一个或零个a字符)、a{1,3}+(尽可能多地匹配一个到三个a字符)、a{3}+(=a{3},三个a)和a*+(匹配零个或多个a字符)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接