当前位置: 首页 > 面试题库 >

如何在JavaScript正则表达式中访问匹配的组?

隆长卿
2023-03-14
问题内容

我想使用正则表达式匹配字符串的一部分,然后访问带括号的子字符串:

var myString = "something format_abc"; // I want "abc"

var arr = /(?:^|\s)format_(.*?)(?:\s|$)/.exec(myString);

console.log(arr);     // Prints: [" format_abc", "abc"] .. so far so good.
console.log(arr[1]);  // Prints: undefined  (???)
console.log(arr[0]);  // Prints: format_undefined (!!!)

我究竟做错了什么?

我发现上面的正则表达式代码没有任何问题:我要针对的实际字符串是:

"date format_%A"

报告“%A”未定义似乎是一个非常奇怪的行为,但与该问题没有直接关系,因此我打开了一个新的代码,
为什么匹配的子字符串在JavaScript中返回“未定义”? 。

问题在于console.log它的参数就像一条printf语句一样,并且由于我正在记录的字符串("%A")具有特殊值,因此它试图查找下一个参数的值。


问题答案:

您可以像这样访问捕获组:

var myString = "something format_abc";

var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;

var match = myRegexp.exec(myString);

console.log(match[1]); // abc

如果存在多个匹配项,则可以对其进行迭代:

var myString = "something format_abc";

var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;

match = myRegexp.exec(myString);

while (match != null) {

  // matched text: match[0]

  // match start: match.index

  // capturing group n: match[n]

  console.log(match[0])

  match = myRegexp.exec(myString);

}

编辑:2019-09-10

如你所见,迭代多个匹配项的方法不是很直观。这导致了该String.prototype.matchAll方法的提出。这种新方法有望在ECMAScript 2020规范中提供。它为我们提供了一个简洁的API,并解决了多个问题。它已经开始登陆主流浏览器和JS引擎,例如Chrome 73 + / Node 12+和Firefox 67+。

该方法返回一个迭代器,其用法如下:

const string = "something format_abc";

const regexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;

const matches = string.matchAll(regexp);



for (const match of matches) {

  console.log(match);

  console.log(match.index)

}

当它返回一个迭代器时,我们可以说它是惰性的,这在处理大量捕获组或非常大的字符串时非常有用。但是,如果需要,可以使用 传播语法
Array.from方法将结果轻松转换为数组:

function getFirstGroup(regexp, str) {
  const array = [...str.matchAll(regexp)];
  return array.map(m => m[1]);
}

// or:
function getFirstGroup(regexp, str) {
  return Array.from(str.matchAll(regexp), m => m[1]);
}

同时,尽管该提案获得了更广泛的支持,但您可以使用官方的shim软件包。

而且,该方法的内部工作很简单。使用生成器功能的等效实现如下:

function* matchAll(str, regexp) {
  const flags = regexp.global ? regexp.flags : regexp.flags + "g";
  const re = new RegExp(regexp, flags);
  let match;
  while (match = re.exec(str)) {
    yield match;
  }
}

创建原始正则表达式的副本;这是为了避免lastIndex在进行多次匹配时由于属性的突变而产生的副作用。

另外,我们需要确保regexp具有 全局 标志以避免无限循环。

我也很高兴看到在提案的讨论中甚至提到了这个StackOverflow问题。



 类似资料:
  • 有没有人试图描述与正则表达式匹配的正则表达式? 由于重复的关键字,这个主题几乎不可能在网上找到。 它可能在实际应用程序中不可用,因为支持正则表达式的语言通常具有解析它们的方法,我们可以将其用于验证,以及一种在代码中分隔正则表达式的方法,可用于搜索目的。 但是我仍然想知道匹配所有正则表达式的正则表达式是什么样子的。应该可以写一个。

  • 给定下面的字符串 [NeMo(PROD)]10.10.100.100(EFA-B-3)[博科FC-Switch]传感器:电源#1(SNMP自定义表)关闭(无此名称(SNMP错误#2)) 我尝试获取多个匹配项以提取以下值: 因为我是正则表达式的初学者,所以我试图定义一些“规则”: 提取第一个圆括号内的第一个值,例如PROD 提取第一个闭合方括号和第二个开口圆括号之间的值,例如10.10.100.10

  • 问题内容: 我正在整理一个相当复杂的正则表达式。表达式的一部分与字符串匹配,例如’+ a’,’-57’等。A+或a- 后跟任意数量的字母或数字。我想匹配0个或更多匹配此模式的字符串。 这是我想出的表达方式: 如果我使用这种模式搜索字符串’-56 + a’,我希望得到两个匹配项: + a和-56 但是,我只得到返回的最后一场比赛: 查看python文档,我看到: 如果一个组多次匹配,则只能访问最后一

  • 我们得到了一些这样的内容:

  • 问题内容: 我想编写一个正则表达式来计算文本块中空格/制表符/换行符的数量。所以我天真地写了以下内容: 由于某些未知原因,它总是返回。上面的陈述有什么问题?此后,我通过以下方法解决了该问题: 问题答案: tl; dr:通用模式计数器 对于那些来到这里的人来说,他们正在寻找一种通用的方法来计算字符串中正则表达式模式的出现次数,并且如果出现的次数为零,也不希望它失败,那么您需要的是这段代码。这是一个示

  • 本文向大家介绍中文正则表达式匹配问题之正则表达式中文匹配使用方法,包括了中文正则表达式匹配问题之正则表达式中文匹配使用方法的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要讲如何使用正则匹配中文字符,中文正则表达式的匹配规则不像其他正则规则一样容易记住,下面一起看看这个中文正则表达式是怎么样的。 \w匹配的仅仅是中文,数字,字母,对于国人来讲,仅匹配中文时常会用到,见下 匹配中文字符的正则表达