C# 将字符串格式化为英国电话号码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/472879/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Format string as UK phone number
提问by Richard Ev
I'm looking for a routine that will format a string of numbers as a UK phone number. The routine should account for UK area codes that require different formatting (i.e. London compared to Edinburgh compared to Worcester) as well as mobile numbers.
我正在寻找将一串数字格式化为英国电话号码的例程。该例程应考虑需要不同格式的英国区号(即伦敦与爱丁堡与伍斯特相比)以及手机号码。
My phone numbers are stored in the database as strings, containing only numeric characters.
我的电话号码以字符串形式存储在数据库中,仅包含数字字符。
So far I have come up with this, but the performance seems poor.
到目前为止,我已经想出了这个,但性能似乎很差。
/// <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;
}
Thoughts welcomed on how to improve this...
欢迎提出有关如何改进这一点的想法......
Edit
编辑
My initial thoughts are that I should store phone numbers as numeric fields in the database, then I can go without the Int64.Parse and knowthat they are truly numeric.
我最初的想法是我应该将电话号码作为数字字段存储在数据库中,然后我可以不用 Int64.Parse 并知道它们是真正的数字。
Edit 2
编辑 2
The phone numbers will all be UK geographic or UK mobile numbers, so special cases like 0800 do not need to be considered
电话号码都将是英国地理或英国手机号码,因此不需要考虑 0800 等特殊情况
采纳答案by Alnitak
UK telephone numbers vary in length from 7 digits to 10 digits, not including the leading zero. "area" codes can vary between 2 and usually 4 (but occasionally 5) digits.
英国电话号码的长度从 7 位到 10 位不等,不包括前导零。“地区”代码可以在 2 位和通常 4 位(但偶尔为 5 位)数字之间变化。
All of the tables that show the area code and total length for each number prefix are available from OFCOM's website. NB: These tables are verylong.
显示每个号码前缀的区号和总长度的所有表格均可从OFCOM 的网站获得。注意:这些表很长。
Also, there's no standard for exactly where spaces are put. Some people might put them in difference places depending on how "readable" it makes the resulting text.
此外,对于放置空格的确切位置也没有标准。有些人可能会将它们放在不同的地方,这取决于它使结果文本的“可读性”。
回答by Rowland Shaw
I'd be tempted to use a tighter set of rules that only check the bear minimum; So on the assumption the leading zero is in the database, pseudo code would be:
我很想使用一套更严格的规则,只检查熊市的最小值;因此,假设前导零在数据库中,伪代码将是:
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. your patterns are slightly wrong 023 is a three digit code, and 0800 is not
注意。你的图案有点错误 023 是一个三位数的代码,而 0800 不是
回答by nrs
** I'm looking for a routine that will format a string of numbers as a UK phone number. **
** 我正在寻找一种将一串数字格式化为英国电话号码的例程。**
You could download the Ofcom database that lists the formats for each number range, including national dialling only numbers, and do a lookup for each number you need to format. The database lists the SABCDE digits and the format: 0+10, 2+8, 3+7, 4+6, 4+5, 5+5, or 5+4 for each range.
您可以下载 Ofcom 数据库,该数据库列出了每个号码范围的格式,包括仅用于国内拨号的号码,并查找您需要格式化的每个号码。数据库列出了每个范围的 SABCDE 数字和格式:0+10、2+8、3+7、4+6、4+5、5+5 或 5+4。
There are a small number of errors in the database (especially for 01697 and 0169 77 codes), but they number less than ten errors in more than a quarter of a million entries.
数据库中存在少量错误(尤其是 01697 和 0169 77 代码),但在超过 100 万个条目的四分之一中,它们的错误数少于 10 个。
There are four files covering 01 and 02 numbers, and separate files for various non-geographic number ranges.
有四个文件涵盖 01 和 02 号码,以及针对各种非地理号码范围的单独文件。
0+10 numbers are 'National Dialling Only' and are written without parentheses around the area code part. The area code will be 02x for all 02 numbers, 01xx for all 011x and 01x1 numbers, and 01xxx for most other 01 numbers (a very small number - about a dozen - will be 01xx xx though).
0+10 号码是“仅限全国拨号”,并且在区号部分周围没有括号。所有 02 号码的区号为 02x,所有 011x 和 01x1 号码的区号为 01xx,大多数其他 01 号码的区号为 01xxx(一个非常小的数字 - 大约一打 - 不过将是 01xx xx)。
Parentheses surround the area code on all other 01 and 02 numbers (that is, use parentheses on 01 and 02 numbers where the local number part does notbegin with a 0 or a 1). Parentheses show that local dialling is possible within the same area by omitting the digits enclosed by the parentheses.
括号包围上的所有其他01和02号(即,使用括号上01和02号在本地数部分不区号不具有0或1开始)。圆括号表示通过省略圆括号括起来的数字,可以在同一区域内进行本地拨号。
The 2+8 nomenclature shows the area code and local number length, with the entry 2075 : 2+8 meaning the number is formatted as (020) 75xx xxxx. Remember the leading zero is not 'counted' in the 2+8 determination.
2+8 命名法显示了区号和本地号码长度,条目 2075 : 2+8 表示该号码的格式为 (020) 75xx xxxx。请记住,在 2+8 确定中不“计算”前导零。
** UK telephone numbers vary in length from 8 digits to 12 digits **
** 英国电话号码的长度从 8 位到 12 位不等 **
No. Since 2000, most have 10 digits after the '0' trunk code. A few still have 9 digits after the '0' trunk code.
不是。自 2000 年以来,大多数在“0”干线代码后都有 10 位数字。少数在“0”干线代码后仍有 9 位数字。
There are also a few special numbers such as 0800 1111 and 0845 4647 to consider.
还有一些特殊号码,例如 0800 1111 和 0845 4647 需要考虑。
** "area" codes can vary between 2 and 4 digits. **
**“地区”代码可以在 2 到 4 位数字之间变化。**
Area codes can vary between 2 and 5 digits (the leading zero is not counted). To be clear, '020' is classed as a 2-digit area code because the leading 0 is actually the trunk code. There are also 011x and 01x1 area codes, and most numbers others have 01xxx area codes. The latter may have local numbers that are only 5 digits long instead of the more widely found 6 digit local numbers. A very small number have an 01xx xx area code and these have 5 or 4 digit local numbers.
区号可以在 2 到 5 位数字之间变化(前导零不计算在内)。需要明确的是,“020”被归类为 2 位区号,因为前导 0 实际上是干线代码。还有 011x 和 01x1 区号,其他大多数号码都有 01xxx 区号。后者可能具有只有 5 位长的本地号码,而不是更广泛使用的 6 位本地号码。一个非常小的号码有 01xx xx 区号,这些号码有 5 或 4 位本地号码。
** Also, there's no standard for exactly where spaces are put. **
** 此外,对于放置空格的确切位置没有标准。**
There is always a space between the area code part and the local number part for all 01 and 02 numbers.
所有 01 和 02 号码的区号部分和本地号码部分之间总是有一个空格。
It is also traditional for (01xx xx) area codes to have a space within the area code as shown. This represents the old local exchange groupings where this system is still in use. Other (shorter) area codes are not split.
(01xx xx) 区号在区号内有一个空格也是传统的,如图所示。这表示该系统仍在使用的旧本地交换分组。其他(较短的)区号不被拆分。
Local numbers with 7 or 8 digits have a split before the fourth digit from the end. Local numbers with 4, 5, or 6 digits are not split. This applies to geographic and non-geographic numbers alike.
7 位或 8 位的本地号码在从末尾算起的第四位数字之前有一个拆分。4 位、5 位或6 位本地号码不拆分。这同样适用于地理和非地理数字。
For most 03, 08, and 09 numbers, the number is written as 0xxx xxx xxxx.
对于大多数 03、08 和 09 号码,号码写为 0xxx xxx xxxx。
Some 0800 and all 0500 numbers are written 0xxx xxxxxx.
一些 0800 和所有 0500 号码都写成 0xxx xxxxxx。
For 055, 056, and 070 numbers the number is written 0xx xxxx xxxx.
对于 055、056 和 070 号码,号码写为 0xx xxxx xxxx。
For mobile and pager numbers, use 07xxx xxxxxx.
对于手机和寻呼机号码,请使用 07xxx xxxxxx。
** except some people use '08000 abc def' instead of '0800 0abc def' **
** 除了有些人使用 '08000 abc def' 而不是 '0800 0abc def' **
That usage is incorrect. Do be aware that some 0800 numbers have 9 digits after the 0 trunk code, whilst others have 10 digits after the 0 trunk code.
这种用法是不正确的。请注意,有些 0800 号码在 0 干线代码后有 9 位数字,而其他号码在 0 干线代码后有 10 位数字。
So, both 0800 xxxxxx and 0800 xxx xxxx are correct.
所以,0800 xxxxxx 和 0800 xxx xxxx 都是正确的。
0500 numbers use only 0500 xxxxxx.
0500 号码仅使用 0500 xxxxxx。
Most 03, 08, and 09 numbers are written written as 0xxx xxx xxxx.
大多数 03、08 和 09 数字都写为 0xxx xxx xxxx。
See also: http://en.wikipedia.org/wiki/Local_conventions_for_writing_telephone_numbers#United_Kingdom
另见:http: //en.wikipedia.org/wiki/Local_conventions_for_writing_telephone_numbers#United_Kingdom
回答by Alastair
I spent some time going through the OFCOM sheets and came up with the following.
我花了一些时间浏览了 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;
}