0

How can I get all matches for [.*], but not if the brackets are backslash-escaped like \[.*\]?

I can use the JavaScript function new RegExp("\\[.*\\]", "g") to get all [.*]. How can I exclude all \[.*\] (escaped brackets)?

Input looks like this:

div\[data-custom-attribute='References'\][matchme]

In this case, the regex should match [matchme].

4

3 回答 3

1

最大的问题是知道您查看的是转义括号 ( \[) 还是转义反斜杠 ( \\[) 后面的括号。如果您只寻找一场比赛,这很容易:

/^[^\]\[\\]*(?:\\.[^\]\[\\]*)*(\[[^\]\[]+\])/

第一部分吞噬除反斜杠或方括号之外的任何字符。如果它看到一个反斜杠,它会抓住那个和下一个字符,不管它是什么。它会尽可能多地重复该过程,当它不能再这样做时,下一件事必须是您正在寻找的括号中的值(或“标签”)。它在第 1 组中被捕获。

获取其余的标签比较棘手。为了与数据保持同步,您希望每个后续匹配都准确地从上一个匹配停止的位置开始。许多正则表达式风格支持\G锚点只是为了这个目的,但它对我们没有帮助。JavaScript 正在采用这个/y标志,它基本上做同样的事情,但你还不能指望它。

这是一个适用于案例的解决方法:

/(?:^|\[[^\]\[]+\])[^\]\[\\]*(?:\\.[^\]\[\\]*)*(?=(\[[^\]\[]+\]))/g

核心正则表达式是相同的,但捕获组现在位于前瞻中。第一次,它像以前一样在字符串的开头开始匹配,但它在第一个标签附近停止。前瞻确认标签存在,但不使用它。下一个匹配从再次匹配标签开始,这次会消耗它。同时,标签也在组#1 中被捕获,因此您可以以通常的方式访问它。

var regex = /(?:^|\[[^\]\[]+\])[^\]\[\\]*(?:\\.[^\]\[\\]*)*(?=(\[[^\]\[]+\]))/g;
var match = regex.exec(subject);
while (match != null) {
    // tag is in match[1]
    match = regex.exec(subject);
}
于 2013-06-24T20:05:48.907 回答
1

http://rubular.com/r/16q3jSPHN0

[^\\](?:\]?(\[(.+?)\]))应该适用于大多数情况。

编辑:

\[test\][test]正如 Rory 指出的那样,这似乎不匹配。为此,如果不使用多个正则表达式,我真的想不出一个好的解决方案,但如果你只想要一个,那么试试这个:http ://rubular.com/r/QBqFAbqW9E

(?:[^\\](?:\]?(\[(.+?)\]))|((?:\]?(\[(.+?)\])))\\)

如果在常规块之后出现带有转义括号的块,则匹配组将填充在前 3 个中,如果出现相反的情况,则在最后 3 个中填充匹配组。

Match 1
1.   
2.   
3.  [test]
4.  [test]
5.  test
Match 2
1.  [test]
2.  test
3.   
4.   
5.   
于 2013-06-24T15:50:17.133 回答
0

使用不可捕获的组,例如[^\\]

[^\\]\[.*[^\\]\]
于 2013-06-24T15:51:13.587 回答