为什么 String.match( / \d*/ ) 返回一个空字符串?

IT技术 javascript regex
2021-02-20 21:41:57

有人可以帮助我理解为什么使用 \d* 返回一个包含空字符串的数组,而使用 \d+ 返回 ["100"] (如预期的那样)。我明白为什么 \d+ 有效,但不明白为什么 \d* 无效。使用 * 是否会导致它返回零长度匹配,这究竟是如何工作的?

var str = 'one to 100';
var regex = /\d*/;
console.log(str.match(regex));
// [""]
4个回答

请记住,match它正在寻找它可以找到的与给定正则表达式匹配的第一个子字符串。

*意味着可能有零个或多个,因此\d*意味着您正在寻找包含零个或多个数字的字符串。

如果您的输入字符串以数字开头,则将匹配整个数字。

"5 to 100".match(/\d*/); // "5"
"5 to 100".match(/\d+/); // "5"

但是由于第一个字符是非数字,因此match()表示字符串的开头(没有字符)与正则表达式匹配。

由于您的字符串不以任何数字开头,因此空字符串是与该正则表达式匹配的输入的第一个子字符串。

谢谢你,@StriplingWarrior。我认为让我感到困惑的是字符串(尽管已填充)以空字符串开头。我没想到字符串“one to 100”包含字符串“”。但是由于正则表达式无法在第一个字符处找到数字,因此它返回空字符串“”,该字符串仍然符合匹配条件,因为“”等于零个或多个数字。但是,如果这符合匹配条件,正则表达式引擎甚至会费心查看第一个字符,如果是,为什么?
2021-04-21 21:41:57
@VadimPushtaev:不,POSIX 正则表达式将返回相同的结果(除非您必须使用[0-9][[:digit:]]代替\d)。只有当正则表达式使用交替时,不同长度的匹配才会成为问题。参考
2021-04-26 21:41:57
这就是 PCRE 所做的,但不是 POSIX 正则表达式。POSIX 总是找到最长的匹配。
2021-05-02 21:41:57
@capolo2:是的,因为正如您从我回答中的代码示例中看到的那样,它必须通过在输入的开头添加到空字符串来知道是否可以匹配更大的字符串(仍然从同一位置开始) .
2021-05-05 21:41:57
@VadimPushtaev:我对正则表达式的所有风格并不十分熟悉,但这就是 Javascript 所做的。
2021-05-11 21:41:57

/\d*/

表示“匹配从字符串开头开始的 0 个或多个数字”。

当您开始字符串的开头时,它会立即遇到一个非数字并且不能再进一步了。然而,这被认为是成功的匹配,因为“0 或更多”。

您可以通过以下方式尝试“1个或多个”

/\d+/

或者您可以告诉它匹配字符串末尾的“0 或更多”:

/\d*$/

在 Python 中查找所有内容

在 Python 中,有一种findall()方法可以返回与正则表达式匹配的字符串的所有部分。

re.findall(r'\d*', 'one to 100')
# => ['', '', '', '', '', '', '', '100', '']

.match() 在 JavaScript 中,只返回第一个匹配项,这将是上述数组中的第一个元素。

啊,区分字符串的开头和结尾有助于将事情弄清楚一点。所以问题是搜索从字符串的开头开始,每个字符串都以空字符串“”开头,这会导致零个或多个数字的匹配成功。如果我的理解不正确,请告诉我。谢谢你的解释,马丁。
2021-04-15 21:41:57
使用 Python 中的示例进行了更新,这可能会进一步阐明。
2021-04-19 21:41:57
就是这样。您从头开始,然后命中一个非数字数字,因此“成功”匹配了 0 个数字数字。
2021-04-24 21:41:57

*意味着 0 或更多,所以它匹配 0 次。您需要使用+1 个或多个。默认情况下它是贪婪的,所以会匹配100

var str = 'one to 100';
var regex = /\d+/;
console.log(str.match(regex));
// ["100"]

正如@StriplingWarrior 在下面所说的,空字符串是第一个匹配项,因此它被返回。我想补充一点,您可以通过注意函数match返回的“索引”字段来判断正则表达式匹配的是什么例如,这就是我在 Chrome 中运行您的代码时得到的结果:

["", index: 0, input: "one to 100"]
谢谢,@Rafid。我将不得不多读一点。我想我不明白为什么它匹配空字符串,当字符串内部有匹配时。另外,关于索引,为什么 '0' 对应于空字符串,而不是字符串中的第一个元素('o')?
2021-04-30 21:41:57