我有这个不错的正则表达式:
*(?:(?:([0-9]+)(?:d| ?days?)(?:, ?| )?)|(?:([0-9]+)(?:h| ?hours?)(?:, ?| )?)|(?:([0-9]+)(?:m| ?minutes?)(?:, ?| )?)|(?:([0-9]+)(?:s| ?seconds?)(?:, ?| )?))+
这几乎符合人类可读的时间增量。它适用于 php、python 和 go,但由于某些原因,捕获组不适用于 javascript。 Here is a working php example在显示工作捕获组的 regex101 上。您会注意到,将其更改为 javascript (ECMAscript) 模式后,捕获组将仅捕获最后一个值。有人可以帮助并澄清我做错了什么,以及它在 js 上不起作用吗?
最佳答案
这里有一个更简单的例子来说明这个问题:
console.log(
'34'.match(/(?:(3)|(4))+/)
);
在PHP中,每当匹配到一个捕获组,它就会被放入结果中。相比之下,在 JavaScript 中,事情要复杂得多:当交替 |
的一侧有捕获组时,每当输入 whole alternation 标记时,就有两种可能性:
- 所采用的交替包含捕获组,结果会将捕获组索引设置为匹配值
- 所采用的交替不包含捕获组,在这种情况下,结果将
undefined
分配给该索引 - 即使捕获组以前匹配过。
这描述了in the specification :
Any capturing parentheses inside a portion of the pattern skipped by | produce undefined values instead of Strings.
和
Step 4 of the RepeatMatcher clears Atom's captures each time Atom is repeated.
because each iteration of the outermost * clears all captured Strings contained in the quantified Atom
在您的情况下,最简单的修复方法是删除重复的最外层捕获组,以便一次只匹配一个子序列,例如 1m
,然后是 1d
,然后遍历匹配项,而不是尝试一次性匹配所有内容。为确保所有匹配项彼此相邻(例如 1m1d
,而不是 1m 1d
),请在遍历匹配项时检查 index
查看它是否与上一场比赛相邻。
关于javascript - 带有量词的正则表达式 Javascript 捕获组不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65056631/