C#中检测无重复字母词(Isogram)的正则表达式修正问题
修复C#中无重复字母词(Isogram)检测的正则问题
需求是编写C#方法检测字符串是否为无重复字母词,其中连字符与空格允许重复。现有正则实现无法正常工作,以下是问题分析与解决方案:
原代码问题分析
原代码中的正则表达式@"^(?:([a-z])(?!=\1)(?:-|\s)?)*$"存在两个核心问题:
- 负向前瞻语法错误:
(?!=\1)写法错误,且逻辑仅检查当前字母紧跟的字符是否重复,无法全局校验该字母在整个字符串中是否重复出现。 - 匹配逻辑缺陷:仅按「字母+可选符号」的循环结构匹配,无法处理符号出现在任意位置的场景,且未忽略符号对字母唯一性判断的干扰。
解决方案
方案1:使用LINQ实现(更直观易维护)
避开正则的复杂逻辑,直接过滤出字母后校验唯一性:
public static bool IsIsogram(string word) { if (string.IsNullOrEmpty(word)) return true; var letters = word.ToLower().Where(c => char.IsLetter(c)); return letters.Distinct().Count() == letters.Count(); }
逻辑说明:
- 将字符串转为小写,避免大小写干扰
- 过滤出所有字母(自动忽略空格、连字符)
- 比较去重后的字母数量与原字母数量,相等则说明无重复
方案2:修正正则表达式
调整正则逻辑,先全局校验是否存在重复字母(忽略非字母字符):
public static bool IsIsogram(string word) => string.IsNullOrEmpty(word) ? true : Regex.IsMatch(word.ToLower(), @"^(?![^a-z]*([a-z])(?=[^a-z]*\1))[a-z\s-]*$");
正则说明:
^(?![^a-z]*([a-z])(?=[^a-z]*\1)):负向预查,若存在任意字母在字符串中重复出现(中间可穿插非字母字符),则匹配失败[a-z\s-]*:匹配任意数量的小写字母、空格或连字符$:匹配字符串结尾
测试验证
三个测试用例均符合预期:
IsIsogram("eleven")→false(存在重复的'e')IsIsogram("isogram")→true(所有字母唯一)IsIsogram("six-years-old")→false(存在重复的's')
内容的提问来源于stack exchange,提问作者Anthony Voronkov
相关产品推荐
相关产品推荐

