寻求匹配仅含3个唯一字符的唯一单词的正则表达式(.NET/C#)
问题需求
给定多行文本输入(已简化):
abc aaaa bcde acd abc abc xyz
需要编写正则表达式,匹配仅出现一次且恰好包含3个唯一字符的单词,预期输出:
acd xyz
尝试的正则(存在缺陷)
(?xmi) ^ (?: ([a-z]) (?!\1) ([a-z]) (?!\1|\2) ([a-z]) ) $
该正则匹配结果:
abc acd abc abc xyz
问题在于abc出现多次却被匹配,需排除这类重复出现的单词,当前使用.NET/C#环境。
解决方案
纯正则实现
在.NET环境中,可结合负向预查/后查,确保单词仅出现一次,同时满足3个唯一字符的要求:
(?xmi)^((?:([a-z])(?!\2)([a-z])(?!\2|\3)[a-z]))$(?<!^\1$\r?\n.*^\1$)(?!.*^\1$\r?\n)
逻辑解释
- 前半段
^((?:([a-z])(?!\2)([a-z])(?!\2|\3)[a-z]))$:确保匹配的单词是3个互不重复的小写字母,和你原正则的核心逻辑一致,调整捕获组是为了方便后续引用整个单词。 - 后半段
(?<!^\1$\r?\n.*^\1$)(?!.*^\1$\r?\n):(?<!^\1$\r?\n.*^\1$):负向后查,保证当前匹配的单词之前没有相同的单词存在。(?!.*^\1$\r?\n):负向前查,保证当前匹配的单词之后没有相同的单词存在。
两者结合实现“单词仅出现一次”的要求。
代码+正则结合实现(更易维护)
如果正则逻辑过于复杂,可先提取所有符合“3个唯一字符”的单词,再通过代码过滤重复项:
var input = @"abc aaaa bcde acd abc abc xyz"; var regex = new Regex(@"^([a-z])(?!\1)([a-z])(?!\1|\2)[a-z]$", RegexOptions.Multiline | RegexOptions.IgnoreCase); var matches = regex.Matches(input).Cast<Match>().Select(m => m.Value); var result = matches.GroupBy(s => s).Where(g => g.Count() == 1).Select(g => g.Key); foreach (var word in result) { Console.WriteLine(word); }
执行这段代码会输出预期的acd和xyz。
内容的提问来源于stack exchange,提问作者user23207089
相关产品推荐
相关产品推荐

