因为“一个+ ?“是懒惰的,为什么“a+?”匹配“aaab"
Since "a+?" is Lazy, Why does "a+?b" Match "aaab"?
在使用 javascript: The Definitive Guide学习javascript正则表达式时,我被下面这段话弄糊涂了:
但/+吗?/匹配字母a的一次或多次出现,匹配为必要时少写几个字。当应用于同一个字符串时,this模式只匹配第一个字母a。
…
现在让我们使用非贪婪版本:/a+?b/。这应该与字母b前面有尽可能少的a。当应用对于同一个字符串" aaab ",您可能希望它只匹配一个a和最后一个字母b。然而,事实上,这种模式匹配整个字符串,就像模式的贪心版本。
为什么会这样?
这是书上的解释:
这是因为正则表达式模式匹配是通过查找完成的字符串中第一个可能匹配的位置。自的第一个字符开始匹配字符串,从后续字符开始的较短匹配永远不会甚至考虑。
我不明白。有人能给我一个更详细的解释吗?
好了,你有了搜索空间"aaabc"和模式/a+?b/
/+吗?B/match "a"?没有。
/+吗?B/匹配"aa"?没有。
/+吗?B/匹配"aaa"?没有。
/+吗?B/匹配"aaab"?是的。
由于您匹配的是文字字符而不是任何类型的通配符,因此正则表达式a+?b
实际上与a+b
是相同的。两者都能匹配的唯一序列类型是一个或多个a
字符后跟一个b
字符的字符串。非贪婪修饰符在这里没有区别,因为a
唯一可能匹配的是a
。
当非贪婪限定符应用于可以取很多不同值的东西时,就变得有趣了,比如.
。(edit或者像a+?
这样左边有有趣的东西的情况)
编辑本;如果您期望a+?b
在aaab
中的b
之前匹配最后一个a
,那么它不是这样工作的。在字符串中搜索模式隐含地意味着搜索该模式最早出现的时间。因此,尽管从最后一个a
开始确实给出了匹配模式的子字符串,但它不是匹配的第一个子字符串。
引擎在字符串开头尝试匹配
谁能给我一个更详细的解释?
是的。
简而言之:.+?
不会在整个字符串的级别上全局查找最短匹配,而是在局部查找,从字符串中引擎当前所在的位置开始查找。
引擎如何工作
当您对字符串aaab
尝试正则表达式时,引擎首先尝试从字符串中的第一个位置开始查找匹配。该位置是第一个a
之前的位置。如果引擎无法在第一个位置找到匹配,则继续从第二个位置(在第一个和第二个a
之间)开始再次尝试
那么可以通过正则表达式a+?b
在第一个位置找到匹配吗?是的。
-
+?
量词告诉引擎匹配所需的最少数量的a
字符。由于我们希望返回匹配,必需意味着必须允许以下令牌(在本例中)匹配。在这种情况下,允许b
匹配所需的a
字符的最少数量是所有剩余的a
字符。 -
b
matches
a
匹配第一个a
在细节中,第二点有点复杂(引擎试图将b
与第二个a
匹配,失败,回溯…),但您不需要担心。
'?+后面的'表示满足表达式的最小字符数。/a+/表示在其他字符前面可以遇到的一个或多个'a'。为了满足/a+?/(因为它不贪婪)它只需要一个'a'。
为了满足/a+?B/,因为我们在末尾有' B ',为了满足这个表达式,它需要在碰到' B '之前匹配一个或多个'a'。它必须碰到'b'。/a+/不需要碰到b,因为RegEx不要求这样做。/+ ?B/必须按那个' B '。
想想看。a+还有别的意思吗?B/本来可以?
希望能有所帮助
- 为什么这个正则表达式不't匹配最后一个字母数字字符
- 为什么JS RegEx提取多个值(只有一个匹配)
- 为什么我网页的facebook点赞数与该网页的facebook页面不匹配
- 为什么我的捕获括号之外的字符包含在我的正则表达式的匹配项中
- 当有多个#时,为什么regex不匹配
- Javascript:为什么要使用indexOf()来匹配字符串中的值
- 为什么函数不会匹配不同数组的宽度和高度
- 为什么我的用户范围的自定义维度会根据过去的匹配而发生变化
- JavaScript 正则表达式 exec() 返回列表中重复的匹配,为什么
- 为什么在 javascript 中将正面回溯捕获为正则表达式匹配的一部分
- 搜索API:为什么“Ondřej”与“ondrej”匹配?我需要在浏览器中模仿它
- 为什么 CSS 选择器只设置第一个匹配 svg 路径的样式
- 为什么在正则表达式字符可选时找不到匹配项
- 为什么这个正则表达式与结束>匹配
- 为什么使用 + 仍然匹配空字符串
- 为什么这个正则表达式必须括在括号中才能匹配
- 为什么我的正则表达式捕获组只在匹配多个部分时捕获字符串的最后一部分
- 为什么 |匹配正则表达式中的每个字符串
- 因为“一个+ ?“是懒惰的,为什么“a+?”匹配“aaab"
- 为什么 ^“ 匹配小于 then 符号 .