【问题标题】:RegEx: How to make greedy quantifier really really greddy (and never give back)?RegEx:如何使贪婪的量词真的很贪婪(并且从不回馈)?
【发布时间】:2017-09-13 18:09:35
【问题描述】:

例如我有这个正则表达式:

([0-9]{1,4})([0-9])

在使用字符串“3041”进行测试时,这给了我这些匹配组:

如您所见,即使量词是贪婪的,group2 也会在 group1 之前填充。

我怎样才能确保在 group2 之前填充 group1?

EDIT1:我想要相同的正则表达式,但 group1 和 group2 中的“3041”为空。

EDIT2:我希望 group1 和 group2 中的“3041”为空。而且,是的,我希望正则表达式匹配!,

【问题讨论】:

  • 你想达到什么目的? [0-9] 是强制模式。如果将第一个设为所有格,则整个模式将永远不会匹配任何字符串。
  • @WiktorStribiżew 我想拥有相同的正则表达式,但在捕获组 1 和捕获组 2 中具有“3041”
  • 使最后一个可选 - ([0-9]{1,4})([0-9]?)
  • @WiktorStribiżew 抱歉,让我再考虑一下,我面前有一个非常复杂的正则表达式,我认为我过于简化了。
  • 好的,慢慢来。

标签: regex


【解决方案1】:

对于输入 "1234",模式:([0-9]{1,4})([0-9]) 尽可能贪婪。

第一个捕获组不能包含四个字符,否则模式的最后一部分将不匹配。

也许您正在寻找的是:

([0-9]{1,4})([0-9]?)

通过使第二组可选地为空,第一组可以包含所有四个字符。

编辑:

我希望正则表达式匹配!,我只希望 5 位字符串匹配整个正则表达式。

在这种情况下,您的模式不应该是第一组中的“1-4 个字符”,因为您想要匹配一组 4 个字符:

([0-9]{4})([0-9])

在某些正则表达式风格中(即并非所有语言都支持这一点),也可以制作量词possessive(尽管在您的情况下这不是必需的,如上所示)。例如:

([0-9]{1,4}+)([0-9])

这将强制尽可能匹配第一个组(即 4 个字符),因此不会尝试 3 个字符的匹配并且整个模式无法匹配。

编辑2:

Javascript 中是否提供“占有欲”?如果没有,有什么解决方法吗?

很遗憾,所有格量词在 JavaScript 中不可用。

但是,您可以通过前瞻来模拟行为(以一种略显丑陋的方式):

(?=([0-9]{1,4}))\1([0-9])

一般来说,所有格量词a++ 可以模拟为:(?=(a+))\1

【讨论】:

  • 我希望 group1 和 group2 中的“3041”为空。而且,是的,我希望正则表达式不匹配!我只希望 5 位数字字符串匹配整个正则表达式。
  • @Emilio 请看我的编辑。我没有意识到您希望字符串 匹配。
  • 对不起,我再次简化了,我不知道我想要多少个字符:/ 我唯一知道的是我想要一种方法来拥有一个不回馈的贪婪量词。有没有可能?
  • 谢谢! (抱歉,我在您发布后发表了评论)Javascript 中是否提供“占有欲”?如果没有,有什么解决方法吗?
  • (如果您在原始问题中包含所有信息,而不是在 cmets 中滴灌它,这将真的有所帮助...)
【解决方案2】:

目前你只需要锚点:

^([0-9]{4})([0-9])$

这将只匹配 五位数字字符串,并且在任何其他字符串上都将失败。

【讨论】:

  • :/ 这只是我拥有的复杂正则表达式的简化。它是较长正则表达式的一小部分。它不是一个独立的正则表达式。
  • @Emilio:我建议不要让我们在黑暗中摸索,而是提供您真实的输入字符串和预期的输出。
  • 相信我,如果我在这里发布真正的正则表达式,你会否决我的问题。我在这里尽我所能:)
  • minimal reproducible example -- 您的示例 最小且可验证,但并不完整
猜你喜欢
  • 1970-01-01
  • 2021-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-27
  • 2021-02-09
  • 2014-02-24
  • 1970-01-01
相关资源
最近更新 更多