我正在寻找一个例程,将一串数字格式化为英国电话号码。该例程应考虑需要不同格式的英国区域代码(即伦敦与爱丁堡相比,与伍斯特相比)以及手机号码。
我的电话号码作为字符串存储在数据库中,仅包含数字字符。
到目前为止,我已经提出了这个问题,但表现似乎很差。
/// <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;
}
欢迎如何改善这一点......
我最初的想法是我应该将电话号码存储为数据库中的数字字段,然后我可以不使用Int64.Parse和知道它们是真正的数字。
电话号码将全部为英国地理或英国手机号码,因此不需要考虑像0800这样的特殊情况
答案 0 :(得分:12)
英国电话号码的长度从7位到10位不等,不包括前导零。 “区域”代码可以在2到4个(但偶尔为5个)数字之间变化。
所有显示每个数字前缀的区号和总长度的表都可从OFCOM's website获得。注意:这些表格非常长。
此外,对于确切放置空间的位置没有标准。有些人可能会把它们放在不同的地方,这取决于它产生文本的“可读性”。
答案 1 :(得分:2)
**我正在寻找一个将一串数字格式化为英国电话号码的例程。 **
您可以下载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(非常小的数字 - 大约十几个 - 将是01xx xx)。
括号围绕所有其他01和02号码上的区号(即,使用01和02号码上的括号,其中本地号码部分不以0或1开头)。括号表示通过省略括号括起来的数字,可以在同一区域内进行本地拨号。
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)区域代码在区域代码中有一个空格,如图所示。这表示此系统仍在使用的旧本地交换分组。其他(较短的)区号不分开。
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'**
该用法不正确。请注意,一些0800号码在0中继码后有9位数字,而其他号码在0中继码后有10位数字。
所以,0800 xxxxxx和0800 xxx xxxx都是正确的。
0500号码仅使用0500 xxxxxx。
大多数03,08和09编号写为0xxx xxx xxxx。
另见: http://en.wikipedia.org/wiki/Local_conventions_for_writing_telephone_numbers#United_Kingdom
答案 2 :(得分:2)
我花了一些时间浏览OFCOM表并提出以下内容。
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;
}
答案 3 :(得分:1)
我很想使用更严格的规则来检查熊的最小值;因此,假设前导零在数据库中,伪代码将是:
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
}
NB。你的模式有点错误023是三位数代码,0800不是