使用正则表达式匹配包含数字字母和短划线的字符串

时间:2011-03-04 09:14:34

标签: c# regex .net-3.5

我需要匹配此字符串011Q-0SH3-936729,但不是345376346asfsdfgsfsdf 它必须包含字符和数字以及破折号

模式可以是011Q-0SH3-936729011Q-0SH3-936729-SDF3000-222-AAAA011Q-0SH3-936729-011Q-0SH3-936729-011Q-0SH3-936729-011Q-0SH3-936729,我希望它能够匹配其中任何一个。原因是我不知道格式是否已修复且我无法找到,所以我需要为具有任意数量的破折号的模式提出通用解决方案,并且模式会重复出现任意数量的次。

对不起,这可能是一个愚蠢的问题,但我真的很喜欢正则表达式。

TIA

5 个答案:

答案 0 :(得分:5)

foundMatch = Regex.IsMatch(subjectString, 
    @"^             # Start of the string
    (?=.*\p{L})     # Assert that there is at least one letter
    (?=.*\p{N})     # and at least one digit
    (?=.*-)         # and at least one dash.
    [\p{L}\p{N}-]*  # Match a string of letters, digits and dashes
    $               # until the end of the string.", 
    RegexOptions.IgnorePatternWhitespace);

应该做你想做的事。如果用字母/数字表示“只有ASCII字母/数字”(也不是国际/ Unicode字母),那么使用

foundMatch = Regex.IsMatch(subjectString, 
    @"^             # Start of the string
    (?=.*[A-Z])     # Assert that there is at least one letter
    (?=.*[0-9])     # and at least one digit
    (?=.*-)         # and at least one dash.
    [A-Z0-9-]*      # Match a string of letters, digits and dashes
    $               # until the end of the string.", 
    RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase);

答案 1 :(得分:4)

修改

这将匹配您的评论中提供的任何密钥:

^[0-9A-Z]+(-[0-9A-Z]+)+$

这意味着钥匙以数字或字母开头,并且有一个短划线符号:

答案 2 :(得分:0)

最天真的实施EVER(可能会让你开始):

([0-9]|[A-Z])+(-)([0-9]|[A-Z])+(-)([0-9]|[A-Z])+

使用Regex Coach进行测试。

编辑:

这只匹配三组;在这里,稍微好一点:

([0-9A-Z]+\-)+([0-9A-Z]+)

答案 3 :(得分:0)

如果没有关于短划线或其他方面的规律性的更多信息,这是我们能做的最好的事情:

Regex.IsMatch(input,@"[A-Z0-9\-]+\-[A-Z0-9]")

虽然这也符合-A-0

答案 4 :(得分:0)

您是将正则表达式应用于整个字符串(即验证还是过滤)?如果是这样,蒂姆的回答应该是正确的。但是如果你从一个更大的字符串中提取匹配项,它会变得更复杂一些。我就是这样做的:

string input = @"Pattern could be 011Q-0SH3-936729 or 011Q-0SH3-936729-SDF3 or 000-222-AAAA or 011Q-0SH3-936729-011Q-0SH3-936729-011Q-0SH3-936729-011Q-0SH3-936729 but not 345-3763-46 or ASFS-DFGS-FSDF or ASD123FGH987.";

Regex pluckingRegex = new Regex(
    @"(?<!\S)         # start of 'word'
      (?=\S*\p{L})    # contains a letter
      (?=\S*\p{N})    # contains a digit
      (?=\S*-)        # contains a hyphen
      [\p{L}\p{N}-]+  # gobble up letters, digits and hyphens only
      (?!\S)          # end of 'word'
    ", RegexOptions.IgnorePatternWhitespace);

foreach (Match m in pluckingRegex.Matches(input))
{
  Console.WriteLine(m.Value);
}

输出:

011Q-0SH3-936729
011Q-0SH3-936729-SDF3
000-222-AAAA
011Q-0SH3-936729-011Q-0SH3-936729-011Q-0SH3-936729-011Q-0SH3-936729

负面外观用作“单词”边界:它们确保匹配的子字符串在字符串的开头或空白字符((?<!\S))之后 开始结束在字符串的末尾或空白字符((?!\S))之前。

三个积极的前瞻工作就像蒂姆一样,除了他们使用\S*跳过第一个字母/数字/连字符之前的任何内容。在这种情况下,我们不能使用.*,因为这样可以跳到下一个单词,或者下一个单词等,从而破坏前瞻的目的。