我有一个用于电话号码字段的 .NET WinForms 文本框。允许自由格式文本后,我想在用户离开文本框后将文本格式化为“更易读”的电话号码。(当您创建/编辑联系人时,Outlook 具有电话字段的此功能)
- 1234567 变为 123-4567
- 1234567890 变为 (123) 456-7890
- (123)456.7890 变为 (123) 456-7890
- 123.4567x123 变为 123-4567 x123
- ETC
一个相当简单的方法是使用正则表达式。根据您接受的电话号码类型,您可以编写一个查找数字的正则表达式(仅限美国,您知道总共可以有 7 或 10 个 - 可能带有前导“1”)和潜在的分隔符它们之间(句点、破折号、括号、空格等)。
对正则表达式运行匹配后,您需要编写逻辑以确定您实际得到的内容并从那里格式化。
编辑:只是想添加一个非常基本的示例(这绝不适用于您上面发布的所有示例)。杰夫关于去除非数字字符的建议可能会有所帮助,具体取决于您编写正则表达式的方式。
Regex regex = new Regex(@"(?<areaCode>([\d]{3}))?[\s.-]?(?<leadingThree>([\d]{3}))[\s.-]?(?<lastFour>([\d]{4}))[x]?(?<extension>[\d]{1,})?");
string phoneNumber = "701 123-4567x324";
Match phoneNumberMatch = regex.Match(phoneNumber);
if(phoneNumberMatch.Success)
{
if (phoneNumberMatch.Groups["areaCode"].Success)
{
Console.WriteLine(phoneNumberMatch.Groups["areaCode"].Value);
}
if (phoneNumberMatch.Groups["leadingThree"].Success)
{
Console.WriteLine(phoneNumberMatch.Groups["leadingThree"].Value);
}
if (phoneNumberMatch.Groups["lastFour"].Success)
{
Console.WriteLine(phoneNumberMatch.Groups["lastFour"].Value);
}
if (phoneNumberMatch.Groups["extension"].Success)
{
Console.WriteLine(phoneNumberMatch.Groups["extension"].Value);
}
}
我认为最简单的方法是首先从字符串中删除任何非数字字符,这样你就只有一个数字,然后按照这个问题中提到的格式进行格式化
我考虑过剥离任何非数字字符然后进行格式化,但我认为这对于扩展案例 (123.4567x123) 不太适用
删除扩展名,然后从其余部分中删除非数字字符。格式化它,然后重新添加扩展名。
Start: 123.4567x123
Lop: 123.4567
Strip: 1234567
Format: 123-4567
Add: 123-4567 x123
这对我有用。如果您在紧密循环中执行此操作,则值得检查性能......
public static string FormatPhoneNumber(string phone)
{
phone = Regex.Replace(phone, @"[^\d]", "");
if (phone.Length == 10)
return Regex.Replace(phone,
"(?<ac>\\d{3})(?<pref>\\d{3})(?<num>\\d{4})",
"(${ac}) ${pref}-${num}");
else if ((phone.Length < 16) && (phone.Length > 10))
return Regex.Replace(phone,
"(?<ac>\\d{3})(?<pref>\\d{3})(?<num>\\d{4})(?<ext>\\d{1,5})",
"(${ac}) ${pref}-${num} x${ext}");
else
return string.Empty;
}
除了自己做一些面具并检查它匹配哪个面具并根据具体情况做每个面具之外,我不知道任何其他方法。不要觉得太难,就是费时间。
我的猜测是,您可以使用条件语句来查看输入,然后将其解析为特定格式来完成此操作。但我猜将会有大量的逻辑来调查输入和格式化输出。