如果匹配,正则表达式会消耗一个字符,但不会消耗

问题描述 投票:0回答:2

我正在尝试编写一个正则表达式,它将捕获'@'字符的所有实例,除非两个这样的字符连续出现(实质上是转义序列)。例如:

abd@ajk@应该匹配

abd@@ajk:没有比赛

abd@@@ajk:最终的@应该匹配。

abd@@@@ajk:没有比赛

这几乎与负前瞻表达式@(?!@)一起使用,除了因为没有消耗第二个@,两个@符号中的最后一个仍将匹配。我认为我想做的是向前看一个@,但如果它在那里消耗该角色;否则,不要消耗它。这可能吗?

编辑:我正在使用Javascript,不幸的是排除了几个好的方法:(

javascript regex regex-lookarounds
2个回答
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修饰符在输入字符串中查找所有匹配的匹配项。


2
投票

既然你没有为你的问题标记编程语言,那么我的Java是2美分:

(?<=(?<!@)(?:@@){0,999})@(?!@)

Java不支持无限的lookbehinds,但在这里有界限我明确指定了偶数出现的@999

JavaScript的

许多浏览器尚未实现和支持JavaScript中的Lookbehinds。如果您尝试在JS中执行此操作,那么这将是您的工作解决方案:

Method 1

((?:[^@]*(?:@@)+[^@]*)+)|@
  • (?:[^@]*(?:@@)+[^@]*)+匹配@@事件及其所有前导/尾随字符
  • |@或单个@

JS代码:

str.split(/((?:[^@]*(?:@@)+[^@]*)+)|@/).filter(Boolean);

Method 2 (Recommended)

或者,如果你没有使用match()的问题,这会更清洁,当然更快:

(?:[^@]*(?:@@)+[^@]*)+|[^@]+

JS代码:

console.log(
  "aaaa@@@@@@@bbb@aa@@@cccc@@ddddd@".match(/(?:[^@]*(?:@@)+[^@]*)+|[^@]+/g)
);
© www.soinside.com 2019 - 2024. All rights reserved.