为啥 String.matchAll() 返回的 Iterable Object 的长度为 1?

Posted

技术标签:

【中文标题】为啥 String.matchAll() 返回的 Iterable Object 的长度为 1?【英文标题】:Why does the Iterable Object returned from String.matchAll() have a length of 1?为什么 String.matchAll() 返回的 Iterable Object 的长度为 1? 【发布时间】:2021-01-29 08:45:45 【问题描述】:

当使用正则表达式通过 matchAll() 从字符串中提取匹配项时,使用扩展运算符扩展为 Array 对象的结果 Iterable 对象显示具有多个成员的嵌套数组。

const regexUpperCaseTo = /(?<=\x2d|\x5f)[a-zA-Z0-9]/g;
const testVar1 = [...str.matchAll(regexUpperCaseTo)]

当我们打印出 testVar1 时,它显示:

[
  [ 's', index: 4, input: 'the-stealth-warrior', groups: undefined ],
  [ 'w', index: 12, input: 'the-stealth-warrior', groups: undefined ]
]

同样,作为一个可迭代对象,我们可以使用 for/of 循环来迭代返回数组的每个元素。

[ 's', index: 4, input: 'the-stealth-warrior', groups: undefined ]
[ 'w', index: 12, input: 'the-stealth-warrior', groups: undefined ]

但是,一旦我们测试每个成员的长度,它就会返回 1。

console.log(testVar1.forEach(x => console.log(x.length)))

除此之外,当我们尝试访问每个数组的第 0 个成员之外的成员时,它会返回 undefined

这是怎么回事,每个返回的成员似乎只包含第一个元素?

【问题讨论】:

你期望的长度是多少? @JaromandaX 那是x[0].length 命名属性不计入数组长度,只计入具有数字索引的属性。 匹配正则表达式返回的数组包含整个匹配的一个元素,然后是所有捕获组的元素。您的正则表达式没有捕获组,因此唯一的元素是完整匹配。 内部数组是长度为 1 的数组(例如,值为“s”),但在该数组上具有组、索引和输入属性,但数组的长度仍为 1 ...例如在你的 forEach 中尝试console.log(x.length, x.input, x.index, x.groups) 【参考方案1】:

这是正常的(与matchAll 返回的迭代器无关)。每个匹配项 - 就像从 .match().exec() 返回的匹配项一样 - 是一个数组对象,其中包含整个匹配项和捕获的组作为元素。

此外,该数组还有一些特殊属性,例如 .index.input 和(自 ES2018 起).groups。另见Return positions of a regex match() in javascript? 或Contents of a RegExp match。

【讨论】:

以上是关于为啥 String.matchAll() 返回的 Iterable Object 的长度为 1?的主要内容,如果未能解决你的问题,请参考以下文章

返回 0 行,为啥?

为啥返回负值

为啥 returnValueMap() 返回 NULL

为啥我的碰撞测试总是返回“真”,为啥图像矩形的位置总是错误的 (0, 0)?

为啥超过 255 的返回码在 C++ 中返回不同的数字?

为啥我不允许在返回 IAsyncEnumerable 的方法中返回 IAsyncEnumerable