为什么 JS Regexp.exec returns 数组的元素比预期的多?

Why JS Regexp.exec returns an array with more elements than expected?

我正在尝试正则表达式匹配各种持续时间字符串(例如 1d10h、30m、90s 等),并想出了一个正则表达式字符串来将字符串拆分成多个部分,但似乎我得到了两个末尾的未定义结果不应该出现。我想这与通过 ? 分组进行的贪婪匹配有关,但我不确定如何解决它。

我的代码如下所示:

const regex = /^(\d+?[d])?(\d+?[h])?(\d+[m])?(\d+[s])?$/gmi
const results = regex.exec('1d10h')

我得到的结果如下所示:

[
  "1d10h",
  "1d",
  "10h",
  undefined,
  undefined,
]

我只期待前三个结果(事实上,我真的只想要 1d10h),但剩下的两个 undefined 结果不断弹出。

正则表达式中有 4 个组 - 每个组都用大括号括起来 ( ... ) 并自然枚举 - 较早的左大括号出现在表达式中组具有的低阶索引.

当然,还有可以命名为“零”组的整场比赛。

因此,regex.exec('1d10h') 的结果包含 5 项:

  • results[0] - 整个表达式匹配
  • results[i] - 每组匹配,i in {1,2,3,4}

因为在这种情况下每个组都是可选的(后跟 ?)- 允许用 undefined 代替任何不匹配的组。

很容易看出,如果在不匹配的组后面删除一个 ? 符号,整个表达式将无法匹配,因此 regex.exec('1d10h') 将 return null.

要删除未定义的元素,只需将它们过滤掉即可:

const result = regex.exec('1d10h').filter(x => x);