2

应用此正则表达式模式:

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

到这个字符串:

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

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

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

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

编辑:我正在尝试匹配有助于 css 选择器的 css 特异性的 html 标记和 css 选择器。因此,我想单独匹配每个lispan等等,而不需要+or >

4

4 回答 4

3

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

要捕获,您需要exec()在字符串上使用正则表达式并遍历结果,其中包含您的捕获组。我还清理了您的模式并对其进行了修改,因此它不会不必要地捕获并且会识别一般的兄弟组合~器:

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
于 2013-02-09T13:31:45.853 回答
2

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

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

此外,您可以使用字符类来避免pipes介于两者之间的字符类,并且您也不需要转义>and +。但请记住,不要caret(^)在字符类的开头使用,否则它将否定一切:

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

您无需转义-_进入角色类。只需-在最后使用,一切都很好。

于 2013-02-09T11:32:03.330 回答
0

你在这里有捕获组:(^| |\>|\+)

于 2013-02-09T11:32:39.213 回答
0

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

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

关于如何在重复(全局)匹配时获取捕获的组,请参阅JavaScript 正则表达式和子匹配。顺便说一句,您也可以尝试使用.split(/[ >+]+/)or .match(/[^ >+]+/g)

于 2013-02-09T12:09:05.880 回答