【问题标题】:Please can someone help me understand the exec method for regular expressions?请问有人可以帮我理解正则表达式的 exec 方法吗?
【发布时间】:2015-06-22 08:44:58
【问题描述】:

我为 exec 方法找到的最佳位置是 Eloquent Javascript Chapter 9:

“正则表达式还有一个 exec(执行)方法,如果没有找到匹配项,它将返回 null,否则返回一个包含匹配信息的对象。从 exec 返回的对象有一个 index 属性,它告诉我们在字符串中的位置成功匹配开始。除此之外,对象看起来(实际上是)一个字符串数组,其第一个元素是匹配的字符串...."

到目前为止,这是有道理的,但后来有点令人困惑:

“当正则表达式包含用括号分组的子表达式时,匹配这些组的文本也将显示在数组中。整个匹配始终是第一个元素。”

好的,但是...

“下一个元素是第一组匹配的部分(左括号在表达式中最先出现的那个),然后是第二组,依此类推。”

var quotedText = /'([^']*)'/;
console.log(quotedText.exec("she said 'hello'"));
// → ["'hello'", "hello"]

我的困惑是在这个例子中重复打招呼。我不明白为什么它会给我两个你好?

然后主题被以下内容包裹起来:

"当一个组最终没有被匹配时(例如,当后面跟着一个问号时),它在输出数组中的位置将保持未定义。同样,当一个组被多次匹配时,只有最后一个match 最终出现在数组中。”

console.log(/bad(ly)?/.exec("bad"));
// → ["bad", undefined]
console.log(/(\d)+/.exec("123"));
// → ["123", "3"]

最后一句话和例子让我很困惑....

对此的任何启示将不胜感激!

【问题讨论】:

  • 一个用于匹配,一个用于捕获
  • “我不明白为什么它会给我两个 hello 回复?” 表达式包含一个捕获组,它偶然捕获了整个匹配。因此,您两次获得相同的值。
  • @FelixKling the expression contains a capture group that incidentally captures the whole match 错误,首先匹配'hello' 2,捕获hello(不带引号)
  • @AvinashRaj:我的错,我错过了报价。似乎OP也可能有;)

标签: javascript regex


【解决方案1】:

我不明白为什么它会回我两个你好?

因为数组中的第一个条目是表达式的整体匹配,然后是表达式定义的任何捕获组的内容。由于表达式定义了一个捕获组,因此您将返回两个条目。 整体匹配是'hello'(带单引号),捕获组是hello(没有它们),因为在正则表达式中,只有hello在捕获组中(括号),而' 在它之外:

vvvvvvvvv-----整体表达 /'([^']*)'/ ^^^^^^^------ 捕获组

让我们看一下/bad(ly)?/ 示例:它所说的是“匹配bad 可选,后跟ly,如果存在ly,则捕获它。”所以你得到:

console.log(/bad(ly)?/.exec("bad"));
// -> ["bad", undefined]
//     ^      ^
//     |      +--- first capture group has nothing in it
//     +---------- overall match is "bad"
console.log(/bad(ly)?/.exec("badly"));
// -> ["badly", "ly"]
//     ^        ^
//     |        +- first capture group has "ly"
//     +---------- overall match is "badly"

假设我们将ly 放在单独的捕获组中,并将它们都设为可选:

console.log(/bad(l)?(y)?/.exec("bad"));
// -> ["bad", undefined, undefined]
//     ^      ^          ^
//     |      |          +--- Nothing in the second capture group
//     |      +-------------- Nothing in the first capture group
//     +--------------------- Overall match is "bad"
console.log(/bad(l)?(y)?/.exec("badly"));
// -> ["badly", "l", "y"]
//     ^        ^    ^
//     |        |    +------- Second capture group has "y"
//     |        +------------ First capture group has "l"
//     +--------------------- Overall match is "badly"
console.log(/bad(l)?(y)?/.exec("badl"));
// -> ["badl", "l", undefined]
//     ^       ^    ^
//     |       |    +-------- Second capture group has nothing in it
//     |       +------------- First capture group has "l"
//     +--------------------- Overall match is "badl"
console.log(/bad(l)?(y)?/.exec("bady"));
// -> ["bady", undefined, "y"]
//     ^       ^          ^
//     |       |          +-- Second capture group has "y"
//     |       +------------- First capture group has nothing in it
//     +--------------------- Overall match is "bady"

【讨论】:

  • 超级简洁,内容丰富!然而,只是另一件事......console.log(/(\d)+/.exec("123")); 在这个例子中,为什么括号会在数字符号(\d)周围产生差异。他们的角色是什么?
  • @Anna:在那个表达中基本上没有任何意义。没有它们的相同表达式,并使用完全匹配的结果,执行该表达式所做的一切。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-28
  • 1970-01-01
  • 1970-01-01
  • 2021-04-25
  • 2021-08-29
  • 2014-12-10
相关资源
最近更新 更多