我经常使用正则表达式,虽然我不是高手,但我也惊讶于这是多么的困难。
我们有一个如下的正则表达式字符串:
^(?:remind me ).*? (to|that|about|its|it's)? ?(.*)$
我希望它与以下两个字符串匹配,* 和 * 为第一个捕获组分配某个值。
- 在24小时测试中提醒我
- 提醒我在24小时内****测试
将这个小“to”分配给第一个捕获组被证明是非常困难的。
我可以像下面这样做两遍,然后检查结果是否是null
,来解决这个问题,但这似乎很疯狂,所以我希望能学到一种更好的方法。
const regex1 = /^(?:remind me ).*? (to|that|about|its|it's)? ?(.*)$/i
const regex2 = /(to|that|about|its|it's) ?(.*)$/i
const matches1 = 'remind me in 24 hours to test'.match(regex1)[2]
const matches2 = matches1.match(regex2)
console.log(matches2)
// String1 output: null
// String2 output: [ 'to test', 'to', 'test', index: 9, input: '24 hours to test', groups: undefined ]
关于相关问题:
我已经看到了许多关于这个问题的其他问题-但没有一个“解决方案”似乎适用于这里,因为大多数答案是定制的用户的具体问题,我还没有能够找出如何解决我们的问题使用他们作为参考。
我读了this answer,它提高了我对贪婪与懒惰的理解,但并没有帮助我理解如何在没有糟糕代码的情况下解决我的问题。
TLDR:所需的结果如下所示,将第一个捕获组中的整个字符串与到进行匹配。第二个捕获组的内容对我们来说并不重要,除非该组不为空。
1条答案
按热度按时间shstlldc1#
如果从 * 第一个捕获组 * 中删除可选量词,并将
.*?
与捕获组一起放入另一个非捕获组中,并使此外部组 * 可选 *,则此方法有效:See this demo at regex101(我还做了一些小的更改,如添加单词边界,更改变量空间的量词,并删除开始时的非捕获组,这看起来是不必要的)
原因就在how backtracking works。我也遇到过类似的情况,不得不摆弄一下。以你现在的模式,最小的匹配成功是留出可选组。但如果外部组被消耗(捕获组内部已设置)没有理由返回。进一步值得记住的是,外部组的
?
是一个 * 贪婪 * quantifier和 * 懒惰 *.*?
内部。