Javascript RegExp非捕获组

Ale*_*erg 11 javascript regex regex-group capturing-group

我正在编写一组RegExps来将CSS选择器转换为id和类的数组.

例如,我希望'#foo #bar'返回['foo','bar'].

我一直在努力实现这一目标

"#foo#bar".match(/((?:#)[a-zA-Z0-9\-_]*)/g)
Run Code Online (Sandbox Code Playgroud)

但是当非捕获前缀?:应该忽略#字符时,它返回['#foo','#bar'].

有没有比切片返回的每个字符串更好的解决方案?

小智 12

您可以使用.replace().exec()在循环中构建数组.

.replace():

var arr = [];
"#foo#bar".replace(/#([a-zA-Z0-9\-_]*)/g, function(s, g1) {
                                               arr.push(g1);
                                          });
Run Code Online (Sandbox Code Playgroud)

.exec():

var arr = [],
    s = "#foo#bar",
    re = /#([a-zA-Z0-9\-_]*)/g,
    item;

while (item = re.exec(s))
    arr.push(item[1]);
Run Code Online (Sandbox Code Playgroud)


Jon*_*Jon 5

它匹配#foo并且#bar因为外部组(#1)正在捕获。该内部组(#2)不是,不过这可能不是你检查什么。

如果您没有使用全局匹配模式,那么直接的解决方法是(/(?:#)([a-zA-Z0-9\-_]*)/改用。

使用全局匹配模式,结果不能只在一行中出现,因为match行为不同。仅使用正则表达式(即没有字符串操作),您需要这样做:

var re = /(?:#)([a-zA-Z0-9\-_]*)/g;
var matches = [], match;
while (match = re.exec("#foo#bar")) {
    matches.push(match[1]);
}
Run Code Online (Sandbox Code Playgroud)

看到它在行动