C#正则表达式验证电话号码

8

我有以下代码用于检查电话号码是否是以下格式 (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) { ....}

2
你试过从一个更简单的正则表达式开始吗(例如,匹配3个数字的正则表达式),然后逐步构建它吗? - Oliver Charlesworth
2
可能是A comprehensive regex for phone number validation的重复问题。 - msarchet
它返回哪些电话号码是 True,而你希望它返回 False?你知道 Regex.Match() 不需要整个字符串匹配吗? - Tim Pietzcker
@TimPietzcker - Tim,我应该使用什么来替换match以检查整个字符串? - Nate Pet
5个回答

14
关于电话号码的正则表达式模式的普遍抱怨是,它们要求将真正可选的字符(如破折号和其他符号)放入其中。为什么不能使它们是可选的,并且模式不在乎它们是否存在呢?下面的模式使用户可以选择是否使用破折号、句点和括号,并专注于数字,使用了命名捕获。该模式是有注释的(使用 # 符号,并跨多行),因此使用 Regex 选项 IgnorePatternWhitespace,除非删除注释。对于该标志不影响正则表达式处理,它只允许通过 # 字符和换行符对模式进行注释。
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)

同一模式的不同变体

没有注释的模式不再需要使用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)

1
接近了,但是 OP 需要在区号后的 ) 后允许一个空格。 - ridgerunner
1
注意 RR。然后将匹配项更改为但不捕获)或.至(?:[).\s]*) # 可选的)或. [和空格] - ΩmegaMan

11

它不 总是 匹配,但是它将匹配任何包含三个数字,一个连字符,四个更多数字的字符串。如果在其前面有像区号一样的东西,它也会匹配。所以,根据您的正则表达式,这是有效的:

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

要验证字符串仅包含电话号码而不包含其他内容,您需要在正则表达式开头和结尾添加锚点

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

6

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

如果你想精确匹配“(XXX) XXX-XXXX”而绝对不匹配其他内容,则需要使用以下代码:

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

6

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

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 - dush88c
太棒了!:) - Will Strohl

2

以上评论都没有考虑到国际电话号码的情况,例如 +33 6 87 17 00 11(这是法国的一个有效电话号码)。 我会采用两步方法: 1. 删除所有不是数字或“+”字符的字符。 2. 检查“+”符号是否在开头或不存在。检查长度(这可能非常困难,因为它取决于当地的国家号码方案)。 现在,如果您的号码以+1开头或您确定用户在美国,则可以应用上述评论。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接