我试图匹配像2h30m,24h,1d20h30s这样的字符串,并用命名组提取每个段。听起来很容易和可行,如果您使用PCRE与正则表达式如下:
^(((?<h>[0-9]+)h)|((?<m>[0-9]+)m))+$
在regexr上的完整示例,您可以在右上角的PCRE和Javascript引擎之间切换。
问题是它在javascript中不起作用,我无法理解为什么。我的猜测是它与OR运算符和命名组之间的交互有关,因为当使用javascript时,它只返回一个命名组
问题是为什么?如果有任何方法可以使这个工作在JavaScript中
似乎应该用|
替换?
以连续捕获几个组(使用|
,只能捕获一行中的最后一组)。我们需要添加一个非空的断言来防止空字符串匹配。此外,值得插入一些?:
使一些组不捕获。
'use strict';
const str = `
2h30m
24h
1d20h30s
`;
const re = /^(?=.+)(?:(?:(?<d>[0-9]+)d)?(?:(?<h>[0-9]+)h)?(?:(?<m>[0-9]+)m)?(?:(?<s>[0-9]+)s)?(?:(?<ms>[0-9]+)ms)?)+$/gm;
let result;
while (result = re.exec(str)) console.log(result.groups);
如果您的Node.js(或浏览器)支持新的matchAll()
方法,也可以通过以下方式实现:
'use strict';
const str = `
2h30m
24h
1d20h30s
`;
const re = /^(?=.+)(?:(?:(?<d>[0-9]+)d)?(?:(?<h>[0-9]+)h)?(?:(?<m>[0-9]+)m)?(?:(?<s>[0-9]+)s)?(?:(?<ms>[0-9]+)ms)?)+$/gm;
console.log(Array.from(str.matchAll(re), ({ groups }) => groups));