正则表达式条件不在最小下划线处返回 false

Regex conditional not returning false on the minimum underscores

如果 RegEx 匹配,我将使用此 RegEx

 if (Regex.IsMatch(_familyname, @"(\S*_){3}\S"))

我试图确保通过测试的单词至少有这个 Word1_Word2_WORD3-maybe_Word4(注意单词中的连字符或空格并不重要) 正则表达式 (\S*_){3}\S 也允许带有两个下划线的单词通过。 是否只有三个下划线的 RegEx 匹配并且这些下划线之间允许任何 word/character/symbol?哦,它也永远不会结束或以下划线开头。此外,如果测试第三个字母数字字符串全部为大写字母会很棒。实际上,我使用字符串拆分实现了所有这些。但是我读到 RegEx 可以更快吗?同时使用 .NET 4.5.2

你的表达是"greedy"试试这个:

if (Regex.IsMatch(familyname, @"(\S*?){3}\S"))

有关详细信息,请参阅: http://www.regular-expressions.info/possessive.html

我不得不添加另一个正则表达式条件来防止用户创建一个带有 4 个下划线的名称,这可以防止最常见的错误,他们可能会添加更多,所以它不是最优雅的解决方案,此外它可能 运行 更慢而不是使用一个正则表达式语句的解决方案。感谢 Mageos 的贪婪、懒惰和占有欲教程,我使用 + 来使用正则表达式风暴获得更少的匹配,所以我猜这是一个比我以前更快的方法。

Regex.IsMatch( 姓氏, @"(\S+){3}\S")
&! Regex.IsMatch(姓氏, @"(\S+){4}\S")

您似乎想要验证一个字符串,该字符串包含大量非空白字符且其中恰好有 3 个下划线。这里的主要问题是 \S 也匹配下划线,这就是为什么你实际上需要 [^\s_] 构造 - 否定字符 class 匹配除空格和 _ 之外的任何字符.

接下来,您要确保匹配的起点前面没有非空格(它还包括 _),因此,您需要负向回顾 (?<!\S)

最后,由于您需要确保除了空格和下划线之外的第 4 个字符块之后没有 _,因此您需要使用 原子组 (因为 .NET 正则表达式中没有所有格量词)以防止回溯到 [^\s_]+ 模式(即只检查在最后一个字符与 [^\s_] 匹配一次后是否没有 _ ).

使用

var res = Regex.IsMatch(str, @"(?<!\S)[^\s_]+(?>_[^\s_]+){3}(?!_)");

regex demo

详情:

  • (?<!\S) - 否定后视确保当前位置左侧没有非空白字符
  • [^\s_]+ - 除空格和 _
  • 以外的 1 个以上字符
  • (?> - 原子组的开始
    • _ - 下划线
    • [^\s_]+ - 除空格和 _
    • 以外的 1 个以上字符
  • ){3} - 精确重复匹配原子组的内容3次
  • (?!_) - 检查一次是否紧靠右边有 _,如果有,匹配失败,否则,return 匹配。

此外,请注意,您可能只是拆分一个字符串,然后检查是否有任何块恰好包含 3 个 _ 个字符,并且只有:

var str = "Word1_Word2_WORD3-maybe_Word4  Word1_Word2_WORD3 Word1_Word2_WORD3-maybe_Word4_Word5";
var res = str.Split().Any(s => s.Count(f => f == '_') == 3);
Console.WriteLine(res ? "Valid" : "Invalid");

参见C# demo