为什么JS Regexp.exec返回的数组包含比预期更多的元素?

问题描述

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

我的代码如下:

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

我得到的结果如下:

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

我只期望前三个结果(实际上,我只想要1d10h),但其余两个undefined结果却不断出现。

解决方法

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

当然,可以将整个匹配称为“零”组。

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

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

由于在这种情况下,每个组都是可选的(后跟?)-允许将undefined替换为任何不匹配的组。

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

要摆脱未定义的元素,只需将它们过滤掉:

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