JavaScript正则表达式迭代器提取组

时间:2011-03-02 11:31:50

标签: javascript regex node.js

假设我们有以下文字:“1 a,2 b,3 c,4 d”和以下表达式:/ \ d(\ w)/ g

我们想要做的是提取正则表达式所表示的a,b,c,d。

不幸的是“1 a,2 b,3 c,4 d”。匹配(/ \ d(\ w)/ g)将产生一个数组:1 a,2 b,3 c,4 d和RegExp。$ 1将仅包含上一场比赛中的组,即RegExp。$ 1 =='d'。

如何迭代这个正则表达式,以便我也可以提取组...我正在寻找一个也是内存效率的解决方案,即某种迭代器对象

编辑: 它必须是通用的。我这里只提供一个简单的例子。一种解决方案是循环遍历数组并为每个项目重新应用正则表达式而不使用全局标志但我发现这个解决方案有点愚蠢,尽管它似乎是唯一的方法。

3 个答案:

答案 0 :(得分:12)

var myregexp = /\d (\w)/g;
var match = myregexp.exec(subject);
while (match != null) {
    // matched text: match[0]
    // match start: match.index
    // capturing group n: match[n]
    match = myregexp.exec(subject);
}

(无耻地取自RegexBuddy

答案 1 :(得分:2)

更短,更简单(虽然可能效率较低)的解决方案是使用String.prototype.replace。 replace是唯一的,因为它隐式迭代所有匹配并为每个匹配执行一个函数。当然,你可以使用该功能来实际替换文本,但尽管功能名称并非真正需要:

"1 a,2 b,3 c,4 d".replace(/\d (\w)/g, function(complete_match, matched_letter) {
    console.log(matched_letter);
});

这会将abc,然后d记录到控制台。 (它也会回归"undefined,undefined,undefined,undefined",但我们在这里并不关心。)

更一般地说,替换is called with the following parameters的函数参数:

function(match, p1, p2, [...], offset, string)
  • match是匹配的子字符串。
  • p1等是匹配的群组,如果有的话。这些组按它们对应的左括号的顺序排列(即最左边的第一个,外面的第一个)。如果该组匹配多个子字符串(即在(.)+方案中),则仅捕获最后一个(最右侧)子字符串。
  • offset是此匹配的原始字符串中的索引
  • string是调用replace的字符串。

手动迭代可能更有效,但这种方法并不慢,而且更短,(恕我直言)更容易阅读;我倾向于在手动循环中使用这种模式。

答案 2 :(得分:1)

这个工作:

"1 a,2 b,3 c,4 d".match(/\w(?:,|$)/g).join(' '); // => "a, b, c, d"

如果您需要迭代:

var r = /\d (\w)/g,
    s = "1 a,2 b,3 c,4 d",
    m;

while ( m = r.exec(s) ) {
    // `m` is your match, `m[1]` is the letter
}