【问题标题】:Phone Number formatting using Regex [duplicate]使用正则表达式的电话号码格式[重复]
【发布时间】:2023-03-21 14:55:01
【问题描述】:

可能重复:
A comprehensive regex for phone number validation

我有一个未格式化的电话号码(保证为 10 位数字)和一个未格式化的分机号(可以是 null、空白或任意数量的数字)。我需要将它们组合成一个“友好”的字符串。我想我会连接它们,然后使用 Regex.Replace 格式化连接。这是我在插入之前用来尝试各种正则表达式的单元测试:

    [Test, Ignore("Sandbox, does not test production code")]
    public void TestPhoneRegex()
    {
        string number = "1234567890";
        string extension = "";

        var formattedContactNumber =
            Regex.Replace("{0} x{1}".FormatWith(number, extension),
                          @"^(\d{3})[ -]?(\d{3})[ -]?(\d{4})( x\d+)?",
                          @"$1-$2-$3$4");

        Debug.WriteLine("{0} x{1}".FormatWith(number, extension));
        Debug.WriteLine(formattedContactNumber);

        Assert.AreEqual("123-456-7890", formattedContactNumber);
    }

预期的格式化字符串是格式化的电话号码,不带“x”和扩展名。但是,最后一个捕获组匹配“x”后面有或没有数字,所以我得到“123-456-7890 x”而不是“123-456-7890”。这是在发布之前需要完成的最后一点开发。帮忙?

【问题讨论】:

  • 从组中删除 x? (x \d+)? 变为 [\sx]*?(\d+)?
  • 当你写exception时,你的意思是extension,对吧?
  • 为什么要在 连接之后格式化它们?
  • 我讨厌这些电话号码格式的东西,因为他们总是假设每个人的号码在相同的模式下都有相同的位数(不!)(不!)
  • @Donal,非常正确,嗯?也许他正在制作一个只适用于北美的应用程序?这里的数字都保证是10位数字(不包括国家代码,包括区号)。

标签: c# regex


【解决方案1】:

x 与您的正则表达式不匹配,因此不会替换字符串的 put。试试这个正则表达式:

@"^(\d{3})[ -]?(\d{3})[ -]?(\d{4}) x(\d*)

在新的正则表达式中x 不是可选的 - 根据您的代码,它将始终存在(如果您确实希望它是可选的,您可以使用?x?(\d*))。此外,我们使用的是\d*,因此请确保最后一个组始终匹配,即使它是空的。

【讨论】:

  • 这是问题所在;因为字符串的结尾不匹配,所以在替换过程中保持不变。我以一种稍微不同的方式解决了它,添加了一个未捕获的 .*$ 来表示我想匹配(并替换)整个字符串,无论我是否捕获了可选部分。
【解决方案2】:

这可能不是您问题的直接答案,但可能会有所帮助......我们使用这种模式:

public const string NorthAmericanPhonePattern = @"^(\+?(?<NatCode>1)\s*[-\/\.]?)?(\((?<AreaCode>\d{3})\)|(?<AreaCode>\d{3}))\s*[-\/\.]?\s*(?<Number1>\d{3})\s*[-\/\.]?\s*(?<Number2>\d{4})\s*(([xX]|[eE][xX][tT])\.?\s*(?<Ext>\d+))*$";

然后重新格式化:

private static string PhoneNumberMatchEvaluator(Match match)
{
    // Format to north american style phone numbers "0 (000) 000-0000"
    //                                          OR  "(000) 000-0000"
    Debug.Assert(match.Success);
    if (match.Groups["NatCode"].Success)
    {
        return match.Result("${NatCode} (${AreaCode}) ${Number1}-${Number2}");
    }
    else
    {
        return match.Result("(${AreaCode}) ${Number1}-${Number2}");
    }
}

private static string FormatPhoneNumber(string phoneNumber)
{
    var regex = new Regex(NorthAmericanPhonePattern, RegexOptions.IgnoreCase);
    return regex.Replace(phoneNumber, new MatchEvaluator(PhoneNumberMatchEvaluator));
}

注意:在我们的案例中,如果他们包含了国家代码,您可以轻松地将其删除。我们也没有在其中包含扩展 - 因为如果我们找到它,我们会将其移出并放入不同的字段。

【讨论】:

    【解决方案3】:

    我喜欢正则表达式,不要误会我的意思,但这似乎不是应用它们的有用领域。您所做的只是将破折号添加到 10 个数字的字符串中,然后添加一个可选的“x”,后跟一个扩展名。越简单越好。

    public static String beautifyPhoneNumber(String number, String extension)
    {
        String beautifulNumber = number.Substring(0, 3) + "-" +
                                 number.Substring(3, 3) + "-" +
                                 number.Substring(6, 4);
        if (!String.IsNullOrEmpty(extension))
        {
            beautifulNumber += " x" + extension;
        }
        return beautifulNumber;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-09-04
      • 1970-01-01
      • 2023-03-11
      • 2014-03-02
      • 1970-01-01
      • 2019-05-23
      • 2023-03-12
      • 2013-08-05
      • 1970-01-01
      相关资源
      最近更新 更多