【问题标题】:Trouble matching alpha and alphanumeric words in string无法匹配字符串中的字母和字母数字单词
【发布时间】:2017-10-09 06:00:16
【问题描述】:

我有以下条件要检查字符串:

  • 至少包含一个字母词
  • 至少包含一个字母数字单词
  • 字母数字单词在任何位置最多可以有一个字母字符,其余的必须是数字(例如:123N123123N12N3。不好:N123NNN123)

到目前为止,我已经尝试了以下方法。它真的很接近,只有第一条测试线(如下所示)没有返回预期的结果。我不太确定这是为什么。我想我一定是忽略了什么。

public static bool ValidLine(string sLine)
{
    //1+ a-z characters
    string alphaRx = @"(\b[a-z]+\b)";
    //1+ numbers with up to 1 letter somewhere
    string alphaNumRx = @"(\b[a-z]?[0-9]+\b|\b[0-9]+[a-z]?\b|\b[0-9]+[a-z]?[0-9]+\b)";

    Regex matchRegex = new Regex(string.Format(@"{0}.*{1}|{1}.*{0}", alphaRx, alphaNumRx));
    return matchRegex.Match(sLine).Success;
}

这是我的测试用例(和预期结果)。只有第一个似乎是问题(这让我怀疑整个模式;它返回 false 尽管它应该被认为是有效的。

string[] sTests = {
    "123 Fake AB",           //true (NOTE: returning false?)
    "123 ",                  //false (no alpha word)
    "123ff bad xy",          //false (alpha numeric has > 1 alpha char)
    "this is bad too",       //false (no alphanumeric)
    "Good one 123   ",       //true
    "s345f 12d234 alpha",    //true 
    "  good st 13",          //true
    " ave po13",             //false (alpha numeric has > 1 alpha char)
    "    123",               //false (no alpha word)
    "    123d",              //false (no alpha word)
    "    123t test",         //true
    "    12r3 test"          //true
};

奖励:有没有一种简洁的方法来简化任何正则表达式?将所有条件组合在一起看起来很混乱。

【问题讨论】:

  • 您的正则表达式区分大小写并检查小写单词,因此FakeAB 都不能匹配。
  • 天哪...@SebastianProske 我在程序的其他地方使用了正则表达式进行不区分大小写的删除,在这里完全忽略了它-_-。我将进行一些更改并重新运行。
  • @DangerZone 不要删除帖子,让 Sebastian 将其发布为答案并接受。
  • Aaaaannnd 这就是问题所在。如果您想快速回答,我会接受。我刚刚更改了以下行:Regex matchRegex = new Regex(string.Format(@"{0}.*{1}|{1}.*{0}", alphaRx, alphaNumRx), RegexOptions.IgnoreCase);
  • @DangerZone 对于这个复杂的东西,你的测试用例太少了。

标签: c# regex


【解决方案1】:

您需要设置IgnoreCase 来解决您最初的问题。


但建议是通过前瞻检查特定规则,并停止对诸如此类的边缘情况的负面前瞻

^                                  # Anchor to start of string
(?=.*\d)                           # Somewhere in the string there is a digit
(?=.*[A-Za-z]{2,})                 # Somewhere in the string there is are a 2 char word
(?!.*\b[A-Za-z]+\d+[A-Za-z]{2,}\b) # Stop on ADAA
(?!.*\d+[A-Za-z]{2,}\b)            # Stop on DAA
(?!.*[A-Za-z]{2,}\d+\b)            # Stop on AAD for `NN123`
.+                                 # If we reach here, we have a valid match, so capture.
$                                  # Anchor to end

使用IgnorePatternWhiteSpace,因为它已被注释,或者删除 cmets 并将其连接在一起。 这是上述模式所需的唯一选项。

这已针对上述所有案例进行了测试,它们的行为符合预期。但我猜你会遇到边缘情况,可能需要新的负面展望或根据需要进行调整。

由于边缘情况的这种性质,我不会解决任何新的边缘情况,请使用我上面的示例作为一个模式,作为所需内容的起点。

【讨论】:

  • cmets 中的“A”和“D”代表“alpha”和“digit”吗?
  • @DangerZone,是的,我需要一个简写来区分注释部分,而不是说“大写和小写字母 ..”。 :-)
猜你喜欢
  • 2022-12-10
  • 1970-01-01
  • 2019-08-14
  • 1970-01-01
  • 1970-01-01
  • 2018-08-30
  • 2011-05-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多