gpt4 book ai didi

javascript - 为什么一个简单的.*?非贪婪的正则表达式贪婪地在比赛前包含额外的字符?

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:59:06 27 4
gpt4 key购买 nike

我有一个与此类似的非常简单的正则表达式:

HOHO.*?_HO_

有了这个测试字符串...

fiwgu_HOHO_HOHO_HOHOrgh_HOHO_feh_HOHO___HO_fbguyev

  • 我希望它只匹配 _HOHO___HO_(最短匹配,非贪婪)
  • 相反,它匹配 _HOHO_HOHO_HOHOrgh_HOHO_feh_HOHO___HO_(最长匹配,看起来很贪婪)。

为什么?我怎样才能让它匹配最短的匹配项?

添加和删除 ? 会得到相同的结果。

编辑 - 更好的测试字符串显示为什么 [^HOHO] 不起作用:fiwgu_HOHO_HOHO_HOHOrgh_HOHO_feh_HOHO_H_O_H_O_HO_fbguye


我能想到的是,也许它匹配了多次——但是 _HO_ 只有一次匹配,所以我不明白为什么它不采用结束于_HO_,丢弃其余部分。

我浏览了所有我能找到的标题为“非贪婪正则表达式贪婪”的问题,但它们似乎都有其他问题。

最佳答案

我在 Regex lazy vs greedy confusion 的帮助下找到了解决方案.

在 Javascript 使用的正则表达式引擎中(NFA engines 我相信),非贪婪只会给你从左到右最短的匹配 - 从第一个左手匹配适合最近的右手匹配项。

如果一个右手匹配有很多左手匹配,它总是从它到达的第一个开始(实际上会给出最长匹配) .

本质上,它一次遍历字符串一个字符,询问“这个字符是否有匹配项?如果有,匹配最短的字符并结束。如果没有,移动到下一个字符,重复”。我预计它会是“此字符串中的任何位置是否有匹配项?如果有,则匹配所有匹配项中最短的一个”。


您可以通过将 . 替换为表示“不是左侧匹配”的否定来近似在两个方向上都非贪婪的正则表达式。至negate a string like this requires negative lookaheads and non-capturing groups ,但这就像将字符串放入 (?:(?!).) 一样简单。例如,(?:(?!HOHO).)

例如,HOHO.*?_HO_ 的左右非贪婪的等价物是:

HOHO(?:(?!HOHO).)*?_HO_

所以正则表达式引擎基本上是这样遍历每个字符的:

  • HOHO - 这与左侧匹配吗?
  • (?:(?!HOHO).)* - 如果是这样,我是否可以在不重复左侧的情况下到达右侧?
  • _HO_ - 如果是这样,捕获所有东西直到右边的匹配
  • ? 修饰符 *+ - 如果有多个右手匹配,选择最近的一个

关于javascript - 为什么一个简单的.*?非贪婪的正则表达式贪婪地在比赛前包含额外的字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27385942/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com