我正在尝试编写一个正则表达式,它将捕获'@'字符的所有实例,除了,当两个这样的字符连续出现时(实质上是转义序列)。例如:
abd@ajk
:@
应匹配
abd@@ajk
:没有匹配
abd@@@ajk
: final @
应匹配。
abd@@@@ajk
:没有匹配
这几乎与负前瞻表达式@(?!@)
一起使用,但由于第二个@
未被消耗,因此两个@
符号中的最后一个仍将匹配。我认为我想做的是向前看@
,但如果它在那里就消耗它;否则,不要消耗它。这可能吗?
编辑:我正在使用Javascript,遗憾的是它排除了几种不错的方法:(
答案 0 :(得分:2)
在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
请参阅its demo
<强>详情
(?:
- 启动与两个备选方案中的任何一个匹配的非捕获组:
- any char other than
@`|
- 或@@
- 2 @
s )+
- 重复匹配1次或更多次。 g
修饰符在输入字符串中查找所有匹配的匹配项。
答案 1 :(得分:2)
由于你没有为你的问题标记编程语言,这里是我的2美分Java:
(?<=(?<!@)(?:@@){0,999})@(?!@)
Java不支持无限的lookbehinds,但是在这里我有明确指定@
999
偶数出现的最大值。
许多浏览器尚未实现和支持JavaScript中的Lookbehinds。如果您尝试在JS中执行此操作,那么这将是您的工作解决方案:
((?:[^@]*(?:@@)+[^@]*)+)|@
(?:[^@]*(?:@@)+[^@]*)+
匹配@@
次出现及其所有前导/尾随字符|@
或单个@
JS代码:
str.split(/((?:[^@]*(?:@@)+[^@]*)+)|@/).filter(Boolean);
或者如果您在使用match()
时没有问题,这会更清洁,当然更快:
(?:[^@]*(?:@@)+[^@]*)+|[^@]+
JS代码:
console.log(
"aaaa@@@@@@@bbb@aa@@@cccc@@ddddd@".match(/(?:[^@]*(?:@@)+[^@]*)+|[^@]+/g)
);