首页 > 解决方案 > 如何在 JavaScript 中标记整个正则表达式?

问题描述

我正在尝试解析时间字符串并将它们转码为我要调用的对象time module。它只是一个具有完整时间披露的简单字典对象。

问题是我必须匹配由数字和时间单位组成的字符串。目前我正在尝试匹配这个正则表达式:
/^(([1-9][0-9]*)(y|m|w|d|h|min|s))+$/g

我需要它来产生每一场比赛。所以如果我给它这个字符串:12y12m12w12d12h12min12s- 它应该返回类似这个数组的东西:

[
    '12y12m12w12d12h12min12s',    // Matching string
    '12y',
    '12',
    'y',
    '12m',
    '12',
    'm',
    '12w',
    '12',
    'w',
    '12d',
    '12',
    'd',
    '12h',
    '12',
    'h',
    '12min',
    '12',
    'min',
    '12s',
    '12',
    's',
    index: 0,
    input: '12y12m12w12d12h12min12s',
    groups: undefined
]

相反,它只返回最后一个单元:

[
    '12y12m12w12d12h12min12s',       
    '12s',
    '12',
    's',
    index: 0,
    input: '12y12m12w12d12h12min12s',
    groups: undefined
]

我可以用 做这件事regex吗?如何?

标签: javascriptregexmatchingregex-group

解决方案


您不应该尝试一次匹配整个输入,因为带有+后缀的捕获组实际上只会捕获最后一个匹配项。

而是迭代子匹配。如果您要求整个字符串最终应该匹配,而没有任何中断的字符序列,则调整您的正则表达式,以便它也匹配单独捕获组中的偏差字符:

let regex = /([1-9][0-9]*)(y|min|m|w|d|h|s)|(.)/g
let s = "12y12m12w12d12h12min12s";
let matches = [...s.matchAll(regex)];
console.log(matches);

因此,输出是一个二维数组,其中每一行有 4 个元素:

  1. 一个时间单位的全场比赛
  2. 数字部分
  3. 单位部分
  4. 如果不是undefined,则此行表示与数字单位模式不匹配的字符

请注意,我在您的正则表达式min之前移动了m,因为您希望匹配优先于min简单m匹配。

您可以过滤该数组以查看第 4 个值是否不匹配。如果没有,数组可以很容易地减少到您的样本输出。

let regex = /([1-9][0-9]*)(y|min|m|w|d|h|s)|(.)/g
let s = "12y12m12w12d12h12min12s";
let matches = [...s.matchAll(regex)];

if (matches.some(row => row[3])) throw "not matching completely";
matches = matches.flatMap(row => row.slice(0,3));
console.log(matches);


推荐阅读