获得正则表达式匹配的所有子组

时间:2010-11-16 22:09:45

标签: javascript regex

给出字符串:

 © 2010 Women’s Flat Track Derby Association (WFTDA) 

我想:

2010 -- Women's -- Flat
Women's -- Flat -- Track
Track -- Derby -- Association

我正在使用正则表达式:

([a-zA-Z]+)\s([A-Z][a-z]*)\s([a-zA-Z]+)

它只是回归:

s -- Flat -- Track

2 个答案:

答案 0 :(得分:9)

这个问题并不简单,但要了解原因,您需要了解正则表达式引擎如何对字符串进行操作。

让我们考虑目标字符串[a-z]{3}上的模式abcdef(匹配a和z之间的3个连续字符)。引擎从字符串的左侧开始(a之前),并看到a[a-z]匹配,因此它前进一个位置。然后,它看到b匹配[a-z]并再次前进。最后,它看到c匹配,再次前进(到d之前)并返回abc作为匹配。

如果引擎设置为返回多个匹配项,它现在将再次尝试匹配,但它会保留其位置信息(因此,如上所述,它将匹配并返回def)。

由于引擎在匹配b时已移过abc,因此bcd永远不会被视为匹配。出于同样的原因,在你的表达式中,一旦匹配一组单词,引擎就永远不会认为第一个匹配中的单词是下一个单词的一部分。


为了解决这个问题,您需要使用lookaheads内的捕获组来收集字符串后面出现的匹配单词:

var str = "2010 Women's Flat Track Derby Association",
    regex = /([a-z0-9']+)(?=\s+([a-z0-9']+)\s+([a-z0-9']+))/ig;

while (match = regex.exec(str))
{
    var group1 = match[1], group2 = match[2], group3 = match[3];
    document.write("Found match: " + group1 + " -- " + group2 + " -- " + group3 + "<br />\n");
}

这导致:

2010 -- Women's -- Flat
Women's -- Flat -- Track
Flat -- Track -- Derby
Track -- Derby -- Association

http://jsfiddle.net/jRgXm/处查看此操作。

正则表达式搜索您似乎定义为单词([a-z0-9']+)的内容,并将其捕获到子组1中,然后使用前瞻(这是一个零宽度断言,因此它不会前进引擎的光标),将接下来的两个单词捕获到子组2和3中。

,如果您使用的是实际的Javascript引擎,则必须 RegExp.exec并循环显示结果(请参阅this question进行讨论为什么)。我不知道UltraEdit的引擎是如何实现的,但希望它可以进行全局搜索并收集子组。

答案 1 :(得分:1)

我正在使用一些通用的正则表达式测试程序,所以我不能保证它对你有用但是......

([A-Z0-9][\w’]+)\s([A-Z][\w]+)\s([A-Z][\w]+)

三个单词以数字或大写字母开头,后跟字母/数字或那个时髦的撇号​​,用空格分隔。适合我。

编辑:我假设你可以循环,在JS中重复匹配器,我从未使用它。