具有非全局正则表达式的“match”和“exec”似乎返回第一个匹配项两次

`match` and `exec` with non-global regex appear to return the first match twice

本文关键字:第一个 两次 返回 正则表达式 全局 match exec      更新时间:2023-09-26

我不太了解JavaScript正则表达式方法的行为。

问题是我无法在没有全局标识符的情况下让 /(something|something)/ 类型的正则表达式使用matchexec方法,例如 /(somereg1|somereg2)/g .

全局标识符存在时,这些方法会正确返回它找到的每个实例。但是当它不存在时,两种方法都正确返回它们找到的第一个匹配项。问题是他们似乎返回了两次。例如:

const str = "Here is somereg1 and somereg2";
str.match(/(somereg1|somereg2)/)

我希望这个match电话能返回"somereg1".相反,它似乎返回"somereg1,somereg1"

检查此 JSFiddle。代码应该是相当不言自明的。第一个例子取自W3Schools。

第一个元素是正则表达式的完全匹配。如果您尝试过此操作:

const str = "Here is somereg1 and somereg2";
str.match(/.*(somereg1|somereg2)/)

您的结果将是[ "Here is somereg1 and somereg2", "somereg2" ] .

.exec(str)方法调用也会发生相同的行为。

您可能想阅读有关.match.exec的信息。

关于"子括号匹配":在正则表达式中,括号分隔捕获组。所以,如果你有这个正则表达式:

/.*(somereg1).*?(somereg2)/

您的.match结果将是[ "Here is somereg1 and somereg2", "somereg1", "somereg2" ]。因此,如您所见,结果数组由完全匹配项组成,后跟所有捕获组匹配项。

并且要强制一个组不被俘虏,只需用(?:)划定界限:

"Here is somereg1 and somereg2".match(/.*(?:somereg1).*?(somereg2)/);
// Will result in [ "Here is somereg1 and somereg2", "somereg2" ].

请注意,g(全局(标志更改了match的返回语义:它们将返回一个完整匹配的数组,捕获组将被忽略。 另一方面,exec 始终返回RegExp实例当前lastIndex之后的匹配的完整匹配和捕获组匹配。为方便起见,可以改用 matchAll,它返回所有匹配项(包括所有捕获组(的迭代器。

您可以使用以下内容来获取请求结果:

var str = "Here is somereg1 and somereg2" //I would expect 
str.match(/(?=(somereg1|somereg2))/)

至于比赛和执行。我会说去匹配,因为它使用正则表达式对象并防止您双重转义,并且全部用于用作 re 的字符串。

修改第二行,如下所示:

str.match(/somereg1|somereg2/)
相关文章: