我常用的正则表达式:
/(?!#REF!)([^!,]{1,99})!/g
我的测试字符串:
foo,#REF!,bar!,baz,qux!
目前它匹配 REF!,但期望的结果是仅匹配
bar!
和 qux!
。我使用了负向先行断言 (?!#REF!)
来防止这种情况,但 REF!
仍然被捕获,因为它与 [^!,]{1,99}
匹配。如何避免匹配 REF!
- 是否使用负向先行断言是正确的方法?我常用的正则表达式:
/(?!#REF!)([^!,]{1,99})!/g
我的测试字符串:
foo,#REF!,bar!,baz,qux!
bar!
和 qux!
。我使用了负向先行断言 (?!#REF!)
来防止这种情况,但 REF!
仍然被捕获,因为它与 [^!,]{1,99}
匹配。如何避免匹配 REF!
- 是否使用负向先行断言是正确的方法?由于你的字符串是逗号分隔的项目列表,因此您可以使用逗号拆分字符串,删除所有空项目(如果有),仅获取以!
结尾的项目,然后从字符串末尾删除!
:
var s = "foo,#REF!,bar!,baz,qux!";
console.log(s.split(',')
.filter(Boolean) // remove empty items
.filter(function (x) {return x.charAt(x.length-1)==="!" && x!== "#REF!";} ) // ends with ! and not #REF!
.map(function(y) {return y.substr(0, y.length-1)}) // remove !
);
/(?:^|,)(?!#REF!)([^!,]{1,99})!/g
访问 Group 1 的值。在此查看正则表达式演示。
注意:这里只有一个捕获组,因为(?!...)
是一个特殊的正则表达式构造,是一个 前瞻。而(?:...)
是一个非捕获组,与捕获组相比,其值不会存储在任何额外的内存缓冲区中。
详情
(?:^|,)
- 起始位置要么是字符串的开头,要么就是,
(?!#REF!)
- 当前位置之后不允许出现#REF!
([^!,]{1,99})
- 捕获组1: 除了!
和,
之外的1到99个字符!
- 一个!
字符var s = "foo,#REF!,bar!,baz,qux!";
var rx = /(?:^|,)(?!#REF!)([^!,]{1,99})!/g, m, res=[];
while (m=rx.exec(s)) {
res.push(m[1]);
}
console.log(res);
您可以使用以下正则表达式:
(?<=^|,)(?!#REF!)([^!,]{1,99})!
解释:
添加 (?<=^|,)
强制你的正则表达式匹配要么从行首开始,要么从前一个逗号开始。如果不添加它,REF!
也会被匹配。逗号 ,
不会成为结果的一部分,因为它在回顾后面的子句中。
如果您不能使用回顾,则可以选择像 WiktorStribizew 提出的解决方案。
(?:^|,)(?!#REF!)([^!,]{1,99}!)
通过引用第1
个捕获组
(?:^|,)(?!#REF!)([^!,]{1,99})!
,您的值在第一组中。顺便说一句,您的模式中只有一个捕获组。 - Wiktor Stribiżew(?:^|,)(?!#REF!)([^!,]{1,99}!)
,否则反向引用将不会考虑到最后一个!
,因为它不会被捕获。 - Allan