C# 将字符串格式化为英国电话号码

C# 将字符串格式化为英国电话号码,c#,regex,formatting,user-interface,C#,Regex,Formatting,User Interface,我正在寻找一个例行程序,将格式化作为英国电话号码字符串。该例行程序应考虑需要不同格式的英国区号(即伦敦与爱丁堡、伍斯特与伍斯特)以及手机号码 我的电话号码以字符串形式存储在数据库中,仅包含数字字符 到目前为止,我已经想出了这个,但性能似乎很差 /// <summary> /// Formats a string as a UK phone number /// </summary> /// <remarks> /// 02012345678 becomes 0

我正在寻找一个例行程序,将格式化作为英国电话号码字符串。该例行程序应考虑需要不同格式的英国区号(即伦敦与爱丁堡、伍斯特与伍斯特)以及手机号码

我的电话号码以字符串形式存储在数据库中,仅包含数字字符

到目前为止,我已经想出了这个,但性能似乎很差

/// <summary>
/// Formats a string as a UK phone number
/// </summary>
/// <remarks>
/// 02012345678 becomes 020 1234 5678
/// 01311234567 becomes 0131 123 4567
/// 01905123456 becomes 01905 123456
/// 07816123456 becomes 07816 123456
/// </remarks>
public static string FormatPhoneNumber(string phoneNumber)
{
    string formattedPhoneNumber = null;

    if (!string.IsNullOrEmpty(phoneNumber))
    {
        System.Text.RegularExpressions.Regex area1 = new System.Text.RegularExpressions.Regex(@"^0[1-9]0");
        System.Text.RegularExpressions.Regex area2 = new System.Text.RegularExpressions.Regex(@"^01[1-9]1");

        string formatString;

        if (area1.Match(phoneNumber).Success)
        {
            formatString = "0{0:00 0000 0000}";
        }
        else if (area2.Match(phoneNumber).Success)
        {
            formatString = "0{0:000 000 0000}";
        }
        else
        {
            formatString = "0{0:0000 000000}";
        }

        formattedPhoneNumber = string.Format(formatString, Int64.Parse(phoneNumber));
    }

    return formattedPhoneNumber;
}
//
///将字符串格式化为英国电话号码
/// 
/// 
///02012345678变为02012345678
///01311234567变为0131 123 4567
///01905123456变为01905 123456
///07816123456变为07816 123456
/// 
公共静态字符串格式phoneNumber(字符串phoneNumber)
{
字符串formattedPhoneNumber=null;
如果(!string.IsNullOrEmpty(phoneNumber))
{
System.Text.RegularExpressions.Regex area1=新建System.Text.RegularExpressions.Regex(@“^0[1-9]0”);
System.Text.RegularExpressions.Regex area2=新建System.Text.RegularExpressions.Regex(“^01[1-9]1”);
字符串格式化字符串;
如果(区域1.匹配(电话号码).成功)
{
formatString=“0{0:00 0000}”;
}
else if(区域2.匹配(电话号码).成功)
{
formatString=“0{0:000 0000}”;
}
其他的
{
formatString=“0{0:0000 000000}”;
}
formattedPhoneNumber=string.Format(formattString,Int64.Parse(phoneNumber));
}
返回格式化的电话号码;
}
欢迎就如何改进这一点提出意见

编辑 我最初的想法是,我应该将电话号码作为数字字段存储在数据库中,这样我就可以不使用Int64.Parse并知道它们是真正的数字

编辑2
电话号码都是英国地理或英国移动电话号码,因此不需要考虑0800等特殊情况

英国电话号码的长度从7位到10位不等,不包括前导零。“区域”代码可以在2到4(但偶尔为5)位之间变化

显示每个号码前缀的区号和总长度的所有表格均可从中获得。注意:这些表格非常长


而且,空间的确切位置也没有标准。有些人可能会根据结果文本的“可读性”将它们放在不同的位置。

我会尝试使用一套更严格的规则,只检查熊市最小值;假设前导零在数据库中,伪代码是:

if( phoneNumber.substring(1,1) == "2" )
{
    // 000 0000 0000
}
else if( phoneNumber.substring(1,1) == "1" && (phoneNumber.substring(1,1) == "2" || phoneNumber.substring(3,1) = "1") )
{
    // 0000 000 0000
}
else
{
    // 00000 000000
}

注意。您的模式有点错误023是一个三位数的代码,0800不是

**我正在寻找一个例程,它可以将一串数字格式化为英国电话号码**

您可以下载Ofcom数据库,该数据库列出了每个号码范围的格式,包括仅限全国拨号的号码,并查找需要格式化的每个号码。数据库列出了SABCDE数字和格式:0+10、2+8、3+7、4+6、4+5、5+5或5+4

数据库中有少量错误(特别是对于01697和0169 77代码),但它们在25多万个条目中的错误数不到10个

有四个文件涵盖01和02编号,以及不同非地理编号范围的单独文件

0+10号码为“仅限全国拨号”,并且在区号部分没有括号。所有02个号码的区号都是02x,所有011x和01x1号码的区号都是01xx,其他01个号码的区号都是01xxx(虽然只有一个非常小的数字——大约12个——是01xx xx)

括号围绕着所有其他01和02号上的区号(即,在本地号码部分不以0或1开头的01和02号上使用括号)。括号表示可以在同一区域内通过省略括号内的数字进行本地拨号

2+8术语表示区号和本地号码长度,条目2075:2+8表示号码格式为(020)75xx xxxx。请记住,在2+8测定中,前导零未“计数”

**英国电话号码的长度从8位到12位不等**

否。自2000年以来,大多数中继代码的“0”后面都有10位数字。少数在“0”中继代码后仍有9位数字

也有一些特殊的数字,如0800、1111、0845、4647等。 **“区域”代码可以在2到4位之间变化**

区号可以在2到5位之间变化(不计算前导零)。需要说明的是,“020”被归类为2位区号,因为前导的0实际上是中继代码。还有011x和01x1区号,其他大多数数字都有01xxx区号。后者可能只有5位数的本地号码,而不是更广泛的6位数本地号码。一个非常小的数字有一个01xx xx区号,这些区号有5位或4位本地号码

**而且,空间的确切位置也没有标准**

对于所有01号和02号,区号部分和本地号码部分之间始终有一个空格

传统上,(01xx xx)区号在区号内有一个空格,如图所示。这表示此系统仍在使用的旧本地exchange分组。其他(较短)区号不拆分

具有7或8位数字的本地数字在从末尾算起的第四位数字之前有一个分隔符。具有4、5或6位数字的本地数字不会被拆分。这同样适用于地理数字和非地理数字

对于大多数03、08和09数字,数字写为0xxx xxx xxxx

一些0800和所有0500数字都写为0xxx xxxxxx

对于055、056和070数字,数字写为0xx xxxx xxxx

对于手机号码和寻呼机号码,请使用07xxx xxxxxx


**除了一些人使用“08000 abc def”而不是“0800 0abc def”**

这种用法是不正确的。一定要知道
public static class TelephoneHelper
{

    #region Regex Patterns
    private static readonly Regex[] patterns = 
    {
        new Regex(@"(?<first>013873)(?<second>\d{5})"),
        new Regex(@"(?<first>015242)(?<second>\d{5})"),
        new Regex(@"(?<first>015394)(?<second>\d{5})"),
        new Regex(@"(?<first>015395)(?<second>\d{5})"),
        new Regex(@"(?<first>015396)(?<second>\d{5})"),
        new Regex(@"(?<first>016973)(?<second>\d{5})"),
        new Regex(@"(?<first>016974)(?<second>\d{5})"),
        new Regex(@"(?<first>016977)(?<second>\d{4}\d?)"),
        new Regex(@"(?<first>017683)(?<second>\d{5})"),
        new Regex(@"(?<first>017684)(?<second>\d{5})"),
        new Regex(@"(?<first>017687)(?<second>\d{5})"),
        new Regex(@"(?<first>019467)(?<second>\d{5})"),
        new Regex(@"(?<first>02\d)(?<second>\d{4})(?<third>\d{4})"),
        new Regex(@"(?<first>03\d{2})(?<second>\d{3})(?<third>\d{4})"),
        new Regex(@"(?<first>0500\d{6})"),
        new Regex(@"(?<first>05\d{3})(?<second>\d{6})"),
        new Regex(@"(?<first>07\d{3})(?<second>\d{6})"),
        new Regex(@"(?<first>08\d{2})(?<second>\d{3})(?<third>\d{3}\d?)"),
        new Regex(@"(?<first>09\d{2})(?<second>\d{3})(?<third>\d{4})"),
        new Regex(@"(?<first>01\d1)(?<second>\d{3})(?<third>\d{4})"),
        new Regex(@"(?<first>011\d)(?<second>\d{3})(?<third>\d{4})"),
        new Regex(@"(?<first>01\d{3})(?<second>\d{5}\d?)")
    };
    #endregion

    public static string FormatAsUkTelephone(this string number)
    {
        Regex matchedPattern = null;
        foreach (Regex pattern in patterns)
        {
            if (pattern.IsMatch(number))
            {
                matchedPattern = pattern;
                break;
            }
        }
        if (matchedPattern != null)
        {
            var mc = matchedPattern.Matches(number);
            if (mc[0].Groups.Count == 3)
            {
                return String.Format("{0} {1}", mc[0].Groups["first"], mc[0].Groups["second"]);
            }
            else if (mc[0].Groups.Count == 4)
            {
                return String.Format("{0} {1} {2}", mc[0].Groups["first"], mc[0].Groups["second"], mc[0].Groups["third"]);
            }
        }
        return number;
    }