【问题标题】:C# Regex Phone Number CheckC# 正则表达式电话号码检查
【发布时间】:2011-12-21 20:41:38
【问题描述】:

我有以下检查电话号码是否为以下格式 (XXX) XXX-XXXX。下面的代码总是返回 true。不知道为什么。

   Match match = Regex.Match(input, @"((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}");

    // Below code always return true
    if (match.Success) { ....}

【问题讨论】:

  • 您是否尝试过从一个更简单的正则表达式(例如一个匹配 3 位数字)开始,然后构建它?
  • 哪些电话号码在您希望它返回 False 的地方返回 True?你知道Regex.Match()不需要整个字符串都匹配吗?
  • @TimPietzcker - Tim,我应该用什么代替 match 来检查整个字符串?

标签: c# .net regex


【解决方案1】:

关于电话号码的正则表达式模式的普遍抱怨是,它们需要将真正可选的字符作为破折号和其他项目。

为什么它们不能是可选的并且有模式不在乎它们是否存在?

以下模式为用户提供了可选的破折号、句点和括号,并使用命名捕获将重点放在数字上。

模式被注释(使用# 并跨越多行)所以使用正则表达式选项IgnorePatternWhitespace 除非删除 cmets。因为该标志不影响正则表达式处理,它只允许通过 # 字符和换行符对模式进行注释。

string pattern = @"
^                  # From Beginning of line
(?:\(?)            # Match but don't capture optional (
(?<AreaCode>\d{3}) # 3 digit area code
(?:[\).\s]?)       # Optional ) or . or space
(?<Prefix>\d{3})   # Prefix
(?:[-\.\s]?)       # optional - or . or space
(?<Suffix>\d{4})   # Suffix
(?!\d)             # Fail if eleventh number found";

上述模式只查找 10 个数字并忽略任何填充字符,例如 ( 或破折号 - 或空格或制表符,甚至是 .。例子是

(555)555-5555 (OK)
5555555555 (ok)
555 555 5555(ok)
555.555.5555 (ok)
55555555556 (not ok - match failure - too many digits)
123.456.789 (failure)

同一模式的不同变体

没有cmets的模式不再需要使用IgnorePatternWhiteSpace

^(?:\(?)(?<AreaCode>\d{3})(?:[\).\s]?)(?<Prefix>\d{3})(?:[-\.\s]?)(?<Suffix>\d{4})(?!\d)

不使用命名捕获时的模式

^(?:\(?)(\d{3})(?:[\).\s]?)(\d{3})(?:[-\.\s]?)(\d{4})(?!\d)

使用ExplicitCapture 选项时的模式

^\(?(?<AreaCode>\d{3})[\).\s]?(?<Prefix>\d{3})[-\.\s](?<Suffix>\d{4})(?!\d)

【讨论】:

  • 关闭,但是OP需要在区号后的)后面留一个空格。
  • 了解 RR。然后更改匹配但不捕获 ) 或 . to (?:[).\s]*) # 可选 ) 或 . [和空间]
【解决方案2】:

它不总是匹配,但它会匹配任何包含三位数字,后跟一个连字符,再跟四个数字的字符串。如果前面有看起来像区号的东西,它也会匹配。所以根据你的正则表达式这是有效的:

%%%%%%%%%%%%%%(999)123-4567%%%%%%%%%%%%%%%%%

要验证字符串是否包含电话号码而没有其他内容,您需要在正则表达式的开头和结尾添加anchors

@"^((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}$"

【讨论】:

    【解决方案3】:

    艾伦摩尔很好地解释了你的经验实际上在做什么。 +1

    如果你想完全匹配 "(XXX) XXX-XXXX" 而绝对没有别的,那么你想要的是

    @"^\(\d{3}\) \d{3}-\d{4}$"
    

    【讨论】:

      【解决方案4】:

      这是我使用的 C# 代码。它旨在从一页文本中获取所有电话号码。它适用于以下模式:0123456789、012-345-6789、(012)-345-6789、(012)3456789 012 3456789、012 345 6789、012 345-6789、(012) 345-6779、012.345

      List<string> phoneList = new List<string>();
      Regex rg = new Regex(@"\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})");
      MatchCollection m = rg.Matches(html);
      foreach (Match g in m)
      {
          if (g.Groups[0].Value.Length > 0)
              phoneList.Add(g.Groups[0].Value);
      }
      

      【讨论】:

      • 这种电话号码怎么样:+9412 345 67891
      • 耶...太棒了! :)
      【解决方案5】:

      上面的 cmets 都不处理像 +33 6 87 17 00 11 这样的国际号码(例如,这是一个适用于法国的有效电话号码)。 我将分两步进行: 1.删​​除所有不是数字或'+'字符的字符 2.检查+号是否在开头。检查长度(这可能非常困难,因为它取决于当地国家号码方案)。 现在,如果您的号码以 +1 开头,或者您确定用户在美国,那么您可以应用上面的 cmets。

      【讨论】:

        猜你喜欢
        • 2011-03-21
        • 1970-01-01
        • 1970-01-01
        • 2017-09-23
        • 2014-02-15
        • 2012-02-13
        • 2015-12-19
        • 2016-02-02
        相关资源
        最近更新 更多