最大的问题是知道您查看的是转义括号 ( \[
) 还是转义反斜杠 ( \\[
) 后面的括号。如果您只寻找一场比赛,这很容易:
/^[^\]\[\\]*(?:\\.[^\]\[\\]*)*(\[[^\]\[]+\])/
第一部分吞噬除反斜杠或方括号之外的任何字符。如果它看到一个反斜杠,它会抓住那个和下一个字符,不管它是什么。它会尽可能多地重复该过程,当它不能再这样做时,下一件事必须是您正在寻找的括号中的值(或“标签”)。它在第 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);
}