给出字符串:
© 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
答案 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中重复匹配器,我从未使用它。