我正在尝试编写一个正则表达式,它将捕获'@'字符的所有实例,除非两个这样的字符连续出现(实质上是转义序列)。例如:
abd@ajk
:@
应该匹配
abd@@ajk
:没有比赛
abd@@@ajk
:最终的@
应该匹配。
abd@@@@ajk
:没有比赛
这几乎与负前瞻表达式@(?!@)
一起使用,除了因为没有消耗第二个@
,两个@
符号中的最后一个仍将匹配。我认为我想做的是向前看一个@
,但如果它在那里消耗该角色;否则,不要消耗它。这可能吗?
编辑:我正在使用Javascript,不幸的是排除了几个好的方法:(
在JavaScript中,要在未转义的@
中拆分字符串,您实际上可以匹配@@
(逃逸的@
)和@
以外的任何字符的文本块:
var strs = ['abd@ajk','abd@@ajk','abd@@@ajk','abd@@@@ajk'];
var rx = /(?:[^@]|@@)+/g;
for (var s of strs) {
console.log(s, "=>", s.match(rx))
}
正则表达式是
/(?:[^@]|@@)+/g
细节
(?:
- 与两个替代方案中的任何一个匹配的非捕获组的开始:
[^ @] - any char other than
@`
|
- 或
@@
- 2 @
s)+
- 重复匹配1次或更多次。g
修饰符在输入字符串中查找所有匹配的匹配项。
既然你没有为你的问题标记编程语言,那么我的Java是2美分:
(?<=(?<!@)(?:@@){0,999})@(?!@)
Java不支持无限的lookbehinds,但在这里有界限我明确指定了偶数出现的@
:999
。
许多浏览器尚未实现和支持JavaScript中的Lookbehinds。如果您尝试在JS中执行此操作,那么这将是您的工作解决方案:
((?:[^@]*(?:@@)+[^@]*)+)|@
(?:[^@]*(?:@@)+[^@]*)+
匹配@@
事件及其所有前导/尾随字符|@
或单个@
JS代码:
str.split(/((?:[^@]*(?:@@)+[^@]*)+)|@/).filter(Boolean);
或者,如果你没有使用match()
的问题,这会更清洁,当然更快:
(?:[^@]*(?:@@)+[^@]*)+|[^@]+
JS代码:
console.log(
"aaaa@@@@@@@bbb@aa@@@cccc@@ddddd@".match(/(?:[^@]*(?:@@)+[^@]*)+|[^@]+/g)
);