javascript - 带有量词的正则表达式 Javascript 捕获组不起作用

标签 javascript regex

我有这个不错的正则表达式:

 *(?:(?:([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/

相关文章:

java - 尝试从 csv 文件构建行时忽略逗号

javascript - 如何在特定字符串之后捕获任何字符串

regex - 是否可以在 perl 中定义单词边界字符集

用于解析存储过程和提取元数据的 C# 脚本

javascript - 等待循环结束,facebook API?

javascript - 监听元素禁用事件

javascript - 如何根据另一个输入 angularJS 验证输入?

javascript - 如何防止用户在 iframe 之外打开我的网络应用程序?

javascript - 检查复选框和单选按钮是否被选中

regex - 以逗号分隔行,仅当引号之间不包含逗号时