为什么这个非捕获组会被捕获?

时间:2013-02-09 11:30:48

标签: javascript regex css-selectors pattern-matching

应用此正则表达式模式:

/(?:(^| |\>|\+))+([a-z\-\_]+)/gi

到这个字符串:

body.test ol+li ol > li #foobar p>span a[href=*]

我得到这些匹配,逗号分隔:

body, ol,+li, ol, > li, p,>span, a

为什么有些匹配的前导空格为>+?我希望我的正则表达式(?:(^| |\>|\+))的这部分符合这些符号,但不会捕获它们。

编辑:我正在尝试匹配html标签和css选择器,这些选择器有助于css选择器的css特异性。因此,我希望自己匹配每个lispan左右,而不是+>

4 个答案:

答案 0 :(得分:3)

捕捉与匹配不同。由于您在模式中指定了组合器,因此匹配器将拾取它们,无论它们是被捕获还是未被捕获。

要捕获,您需要exec()字符串上的正则表达式并循环显示结果,包含您的捕获组。我还清理了你的模式并对其进行了修改,使其不会被不必要地捕获并识别the general sibling combinator ~

var sel = "body.test ol+li ol > li #foobar p>span a[href=*]";
var re = /(?:^| |>|\+|~)+([a-z_-]+)/gi;
var matches = [], m;

while (m = re.exec(sel)) {
    matches.push(m[1]);
}

然后您将获得预期的匹配:

body, ol, li, ol, li, p, span, a

答案 1 :(得分:2)

(?:(^| |\>|\+))中的内部括号正在创建一个捕获的组。你也可以让它不被捕获,我想,你应该在外括号内有+量词:

/(?:(?:^| |\>|\+)+)([a-z\-\_]+)/gi

此外,您可以使用字符类来避免在其间使用pipes,而且您也不需要转义>+。但请记住,不要在角色类的开头使用caret(^),否则它会否定一切:

/(?:[ >+^]+)([a-z_-]+)/gi

您不需要在字符类中转义-_。只需在最后使用-,一切都很好。

答案 2 :(得分:0)

您在此处拥有捕获组:(^| |\>|\+)

答案 3 :(得分:0)

您有两个捕获组(^| |\>|\+)([a-z\-\_]+) - 第一个直接位于非捕获组内。只需删除它:

/(?:^| |>|\+)+([a-z_-]+)/gi

关于如何在重复(全局)匹配时获取捕获的组,请参阅JavaScript regular expressions and sub-matches。顺便说一句,您也可以尝试使用.split(/[ >+]+/).match(/[^ >+]+/g)