javascript - 为什么在 regex char 可选时找不到匹配项

标签 javascript regex regex-greedy

我很困惑为什么会这样,希望有人能解释正则表达式引擎中发生的事情的机制。

在进行代码战练习时“您的意思是……?”在 Javascript 中,我试图计算 word1 中有多少字符出现在 word2 中。我尝试将每个字符作为其自己的匹配组进行匹配,以便稍后我可以计算数组中成功匹配的数量,并使用它来找出这两个词的相似程度。

请不要给我提示如何解决 codewars 挑战,只是帮助我理解这里发生了什么。

我试过:

'berry'.match(/(c?)(h?)(e?)(r?)(r?)(y?)/)

没有匹配到

> ["", "", "", "", "", "", ""]

这对我来说是个谜。搜索 Regular-expressions.info 后,?(使前面的字符可选)是贪婪的,所以虽然没有匹配对正则表达式有效,但它不应该首先被贪婪版本打败吗?我期待这个:

> ["", "", "", "e", "r", "r", "y"]

我尝试过的其他事情: - cherry match cherry 工作正常

'cherry'.match(/(c?)(h?)(e?)(r?)(r?)(y?)/)
> ["cherry", "c", "h", "e", "r", "r", "y"]

cherl match cherry 也像我期望的那样工作

'cherl'.match(/(c?)(h?)(e?)(r?)(r?)(y?)/)
> ["cher", "c", "h", "e", "r", "", ""]

如果我从最后的 y 中删除 ?,它也会按预期工作:

'berry'.match(/(c?)(h?)(e?)(r?)(r?)(y)/)
> ["erry", "", "", "e", "r", "r", "y"]

那么为什么在最后的 y 上添加 ? 意味着我不再看到任何匹配的字符?

虽然我在 JS 中尝试过这个,但我在 PY 和 PCRE 中得到了相同的结果

最佳答案

So why does adding a ? onto the final y mean I no longer see any matched characters?

您一开始使用的模式 - /(c?)(h?)(e?)(r?)(r?)(y?)/ - 可以匹配空字符串,因为所有子模式都是可选的(即可以匹配零次)。当您只查找一个匹配项时(例如,使用 JavaScript 中的 String#match),您将始终获得位于字符串最开头的匹配项(因为在大多数情况下,正则表达式引擎会从左到右分析字符串),空字符串(如果第一个字符无法与第一个子模式匹配)或某个子字符串(如果前导或所有子模式匹配)。

所以,berryb 开头. /(c?)(h?)(e?)(r?)(r?)(y?)/以可选的 c 开头,因此,b无法与 c 匹配它失败了。 b然后不能与 h 匹配, 也不 e , 也不 r , 也不是另一个 r , 也不 y .请注意,如果您更改最后一个 y?b? ,你will get a b in the match .

如果你不使用/g (全局)标志在 JS 正则表达式中,引擎将只检查一个匹配项。它会在开头找到它 - 一个空字符串,返回它并收工。 If you use /g ,它将检查所有位置,第二场比赛将为您提供所需的结果。但是,当您使用 String#match()/g基于正则表达式,您将丢失捕获的子字符串。使用 RegExp#exec()能够访问这些子匹配项。

请注意 /(c?)(h?)(e?)(r?)(r?)(y)/给你匹配,因为最后一个 y强制性的并且模式不能再匹配空字符串。因此,当引擎看到 bberry ,匹配失败,继续检查 e 之前的下一个位置, 并在那里找到匹配项。因此,没有 /g在这种情况下是必要的。

关于javascript - 为什么在 regex char 可选时找不到匹配项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35501184/

相关文章:

javascript - 如何在替换对象的循环中替换字符串?

javascript - 使用 jQuery 从一个位置复制文本,以替换其他位置的文本

c# - 用于在数字模式和冒号或换行符之间提取字符串的正则表达式

Python 电话号码正则表达式

regex - Perl 正则表达式不够贪婪

javascript - 提取部分URL JS

javascript - 当主体函数进行条件检查时,useEffect 钩子(Hook)应该返回什么?

regex - Perl:用它们的计数替换连续的数字

regex - 替换 Powershell 字符串中的路径

python - 当文本略有不同时替换列名称