在字符串中查找多个非连续出现的字符

时间:2017-07-27 08:42:56

标签: c# regex string

有人可以帮我写一个RegEx表达式,它可以检查一个字符串是否包含多个大写(或小写,无关紧要)字母但不是连续出现。 我需要在字符串中至少出现两次(甚至更好的n次)事件。如果n = 2,则有效情况将是PassWord或PAssword或PASSWord。

当我尝试这个/(?=([A-Z]{2,3}))/g时,它匹配PassWOrd而不是PassWord。

我觉得奇怪的是它也与PaSSWOrd相匹配。我认为{2,3}中的3实际上意味着不会再匹配3个大写字符。为什么SSWO匹配?

我尝试了类似的变化,但没有为我工作(没什么奇怪的,因为我对RegEx不太熟悉)。

可以使用RegEx完成吗?

1 个答案:

答案 0 :(得分:4)

(?=([A-Z]{2,3}))正则表达式匹配字符串中的2到3个连续大写ASCII字母。您希望匹配仅包含2到3个大写ASCII字母的字符串,不一定是连续的。

要匹配仅包含两个大写ASCII字母(不多于不少)的字符串,请使用以下表达式:

^(?:[^A-Z]*[A-Z]){2}[^A-Z]*$

或者,如果您只允许整个字符串中的ASCII字母:

^(?:[a-z]*[A-Z]){2}[a-z]*$

请参阅regex demo

模式详情

  • ^ - 字符串开头
  • (?:[^A-Z]*[A-Z]){2} - 正好发生2次
    • [^A-Z]* - 除ASCII大写字母以外的零个或多个字符
    • [A-Z] - 一个ASCII大写字母
  • [^A-Z]* - 除ASCII大写字母以外的零个或多个字符
  • $ - 字符串结束。

在C#中,使用

var strs = new List<string> { "PassWord", "PAssword", "PASSWord"};
var n = 2;
var pat = $@"^(?:[^A-Z]*[A-Z]){{{n}}}[^A-Z]*$";
foreach (var s in strs) {
    Console.WriteLine("{0}: {1}", s, Regex.IsMatch(s, pat));
}

结果:

PassWord: True
PAssword: True
PASSWord: False

请参阅online demo

请注意,如果您需要在字符串中需要2个大写ASCII字母,其他字符可以是任何字符,您不需要正则表达式,请使用LINQ:

var strs = new List<string> { "PassWord", "PAssword", "PASSWord"};
var n = 2;
foreach (var s in strs) {
    var res = s.Count(c => (c >= 65 && c <= 90));
    Console.WriteLine("{0}: {1}", s, res == 2);
}

another demo.Count(c => (c >= 65 && c <= 90))部分将计算字符串中任何位置的大写ASCII字母,res==2将返回布尔结果,无论数字是否等于2。它可以轻松调整为数值范围检查。

如果您需要Unicode兼容性,请将.Count(c => (c >= 65 && c <= 90))替换为.Where(Char.IsUpper)