正则表达式中加号和星号有什么区别?

129

两者之间有什么区别:

(.+?)

(.*?)

当我在PHP的preg_match正则表达式中使用它时,会发生什么?

9个回答

205

它们被称为量词。

* 表示匹配 0 或多个前面的表达式

+ 表示匹配 1 或多个前面的表达式

默认情况下,量词是贪婪的,这意味着它会尽可能地匹配更多的字符。

在量词后面加上 ? 可以将其行为更改为“非贪婪”,这意味着它会尽可能地匹配更少的字符。

贪婪/非贪婪示例

例如,在字符串 "abab" 上:

a.*b 将匹配 "abab"(preg_match_all 将返回一个匹配项,即 "abab")

a.*?b 只会匹配起始的 "ab"(preg_match_all 将返回两个匹配项,即 "ab")

您可以在 Regexr 等网站上在线测试正则表达式,在此查看贪婪示例


6
“懒惰”是“不贪婪”的更常见的说法。 - Walter Tross
这个例子是不正确的。在正则表达式的各种位置上,(.+?)(.*?)的行为是不同的,这些位置包括a(.+?)(.+?)ba(.+?)ba(.*?)(.*?)ba(.*?)b - Louis55
为什么a.*b不能返回“ab”?它不是在说“在a和b之间有0个或多个字符的单词”,因此,ab之间没有字符可以匹配。为什么这是不正确的? - Hello World
@HelloWorld,这与我上面解释的贪婪性有关。.*将尽可能匹配。如果你想尽早停止匹配,那么你必须使它变成非贪婪的.*? - stema
给新手的提示:如果使用“g”(全局)标志,a.*?b 将匹配 "abab" 中的第 1 个和第 2 个 "ab"。此外,在这个特定的解释中,“ungreedy”一词比“lazy”更好,因为“lazy”是编程中常用的术语,并且与本示例中 ? 的作用有点不同。 - starriet

23
第一个(+)表示一个或多个字符。第二个(*)表示零个或多个字符。
两者都有贪婪(默认)和懒惰(?)的变体。
/d+?
/d*?

1
这取决于是否设置了 s 修饰符。 - Quentin

17
在正则表达式中,{i,f} 表示“匹配次数在 if 之间”。让我们看一下以下几个例子:
  • {3,7} 表示匹配3到7次
  • {,10} 表示最多匹配10次而没有下限(即下限为0)
  • {3,} 表示至少匹配3次而没有上限(即上限为无穷大)
  • {,} 表示不限制匹配次数(即下限为0且上限为无穷大)
  • {5} 表示恰好匹配4次

大多数好的语言都包含缩写,正则表达式也是如此:

  • +{1,} 的简写
  • *{,} 的简写
  • ?{,1} 的简写

这意味着 + 至少需要匹配一次,而 * 可以接受任意数量的匹配或者根本不匹配, ? 最多可以匹配一次或零次。

来源:Codecademy.com


11

+ 匹配至少一个字符

* 匹配任意数量(包括 0)的字符

? 表示懒惰模式,它将匹配尽可能少的字符。


10

+表示匹配前面的模式一次或多次。而*表示匹配前面的模式零次或多次

简单来说,如果使用+,则必须至少有一个模式实例与之匹配;如果使用*,即使没有任何模式实例与之匹配,也仍然会匹配成功。


9
考虑下面的字符串需要匹配。
ab

模式(ab.*)将返回一个捕获组的匹配结果ab

而模式(ab.+)不会匹配任何内容,也不会返回任何结果。

但是如果你将字符串更改为以下内容,则模式(ab.+)将返回aba

aba

6

+ 是至少一次的匹配,* 可以是零次或多次的匹配。


3
“+ is minimal one”这句话是什么意思?这句话的意思是“+是最小的一个”。 - Det
我认为这些“定义”具有误导性。 - mickmackusa

5
一个星号与加号非常相似,唯一的区别在于,加号匹配一个或多个前面的字符/组,而星号则匹配零个或多个。

0

我认为之前的回答没有突出一个简单的例子:

比如我们有一个数组:

numbers = [5, 15]

以下正则表达式^[0-9]+只匹配15。但是,^[0-9]*会同时匹配5和15。不同之处在于+操作符要求至少有一个重复前面的正则表达式。

什么?!?为什么这个答案被点赞了?这是完全错误的。两种模式都肯定会匹配字符串515 - mickmackusa

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