我想要与使用一个正则表达式的字符串的一部分相匹配,然后访问该带括号的子字符串︰

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") 的字符串有一个特殊值,试图找到下一个参数的值。

2009-01-11 07:21:20
问题评论:

回答:

您可以访问此类捕获组︰

var myString = "something format_abc";
var myRegexp = /(?:^|s)format_(.*?)(?:s|$)/g;
var match = myRegexp.exec(myString);
alert(match[1]);  // abc

并且,如果有多个匹配项,您可以循环访问它们︰

match = myRegexp.exec(myString);
while (match != null) {
    // matched text: match[0]
    // match start: match.index
    // capturing group n: match[n]
    match = myRegexp.exec(myString);
}

+ 1 请注意,在第二个示例,您应该使用 RegExp 对象 (不只"/myregexp/"),因为它将 lastIndex 值的对象中。而无需使用 Regexp 对象它将循环无限

@ianaz︰ 我并不认为 tis 真?http://jsfiddle.net/weEg9/似乎至少从事镶边。

为什么上面而不是︰ var match = myString.match(myRegexp); // alert(match[1])?

不需要进行显式"新 RegExp",但是会发生无限循环,除非指定 /g

另一种不会遇到无限循环是为 explicetly 更新字符串,如string = string.substring(match.index + match[0].length)

这是一种方法可以用于获取每个匹配项的n个捕获组︰

function getMatches(string, regex, index) {
  index || (index = 1); // default to the first capturing group
  var matches = [];
  var match;
  while (match = regex.exec(string)) {
    matches.push(match[index]);
  }
  return matches;
}


// Example :
var myString = 'something format_abc something format_def something format_ghi';
var myRegEx = /(?:^|s)format_(.*?)(?:s|$)/g;

// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);

// Log results
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
console.log(matches);

这远优于回应其他人因为它正确地显示所有匹配项,而不是仅使一个迭代。

mnn 是正确的。如果 g 标记不存在,这将产生一个无限循环。要使用此函数非常小心。

我改进此选项以制作类似于 python 的 re.findall()。它向上的所有匹配项分组为数组的数组。它还会修复全局修饰无限循环问题。jsfiddle.net/ravishi/MbwpV

@MichaelMikowski 现在已经不仅仅是隐藏您无限循环,但是您的代码将运行缓慢。我认为最好的代码是中断以错误的方式,以便您在开发过程中捕捉到它。放一些营业中断中的最大迭代数是草率的。隐藏问题,而不是解决其根本原因不是答案。

当您不碰到执行限制没有意义地慢的 @MichaelMikowski。时,很清楚地变得更慢。我并不说您的代码不起作用,我并说,实际上我认为它将导致大于功。在开发环境中工作的人将看到尽管做 10000 不必要执行代码的某些块无负载的情况下正常工作的代码。然后他们将推送到生产环境,并想知道为什么他们的应用程序出现故障在负载下。我的经验最好如果事情破坏以明显的方式,和前面的开发周期。

var myString = "something format_abc";
var arr = myString.match(/format_(.*?)/);
console.log(arr[0] + " " + arr[1]);

不是完全相同的目标 (适用于"— format_foo /","format_a_b"上不起作用) 也是如此...但我想让您的表达式,它是很好的替代方法。当然,匹配调用是重要的事情。

它是完全相反。分隔的单词。word = 'w' = [a-zA-Z0-9_]。"format_a_b"是一个字。

@B.F.Honestly,添加"不起作用在format_a_b后思想作为 6 年前,我不记得我含义那里...:-)我想它意味着"不起作用以捕获a仅",ie。format_之后的第一个字母部分.

我想要说的是,(-format_foo /} 不返回"— format_foo /"因为"-"和"/"没有单词字符。但返回"format_a_b"(format_a_b) 执行。对吧?我是指您在圆括号中的文本语句。(这么做无下投票了 !)

语法可能不是最好的保持。FF/Gecko 定义的函数的扩展的 RegExp。
(FF2 去至于typeof(/pattern/) == 'function')

似乎这是特定于 FF--IE、 Opera 和 Chrome 所有引发该异常。

相反,使用前面提到的其他任何一种方法︰ RegExp#execString#match.
它们提供了相同的结果︰

var regex = /(?:^|s)format_(.*?)(?:s|$)/;
var input = "something format_abc";

regex(input);        //=> [" format_abc", "abc"]
regex.exec(input);   //=> [" format_abc", "abc"]
input.match(regex);  //=> [" format_abc", "abc"]

在上面的示例多匹配括号方面,我在寻找后没有得到什么我想要的答案︰

var matches = mystring.match(/(?:neededToMatchButNotWantedInResult)(matchWanted)/igm);

查看时稍微复杂的函数调用和上面的.push() 后, 恍然大悟我,可以解决问题很雅观的 mystring.replace() 改为 (替换内容并不重要,并不甚至完成后,清理,内置的递归函数调用选项的第二个参数是 !)︰

var yourstring = 'something format_abc something format_def something format_ghi';

var matches = [];
yourstring.replace(/format_([^s]+)/igm, function(m, p1){ matches.push(p1); } );

此后,我并不认为我曾经将尸体将.match() 用于几乎没什么东西。

请输入您的翻译

How do you access the matched groups in a JavaScript regular expression?

确认取消