65.9K
CodeProject 正在变化。 阅读更多。
Home

高级电话号码类型实现

starIconstarIconstarIconstarIconstarIcon

5.00/5 (5投票s)

2008 年 12 月 24 日

CPOL

5分钟阅读

viewsIcon

51124

downloadIcon

845

一个可用于解析、验证和规范化电话号码的电话号码结构。

引言

在许多应用中都需要解析、规范化和验证电话号码。本文提供了一个单一的结构化类型,可让您轻松地解析、规范化和验证 NANP(北美号码计划)电话号码。它也应该支持国际电话号码,但我尚未用国际号码进行过测试。它还支持电话号码的语音表示(例如 1-800-MY-PHONE)。

背景

我遇到了许多情况,需要在 Web 表单上的用户输入中解析、规范化和验证电话号码,因此 PhoneNumber 结构应运而生。最初它只是一个只能解析有限格式的简单结构,随着时间的推移,我为其添加了更高级的解析功能,甚至增加了语音电话号码支持。在解析带有分机号的电话号码时,它仍然有一些局限性,但大多数情况下,它能够处理我遇到的几乎所有格式。

该结构最初仅用于规范化和验证 NANP 号码,但它应该也能处理国际电话号码。唯一的例外可能是国家代码使用字母数字代码而不是纯数字代码的情况。  不过我尚未用该结构测试过任何国际电话号码。

如果您有兴趣了解更多关于 NANP 的信息,老牌的 Wikipedia 可能是最好的阅读地点。

Using the Code

代码文件已完全文档化,并包含不少示例,因此我在这里仅提供一些基本示例来展示该结构的功能。

// Create a basic instance by specifying integer values.
PhoneNumber phone = new PhoneNumber(1, 800, 222, 2222, 1234);
Console.WriteLine(phone); // output: (800) 222-2222 ext 1234

// Create an instance by parsing a numerical string
PhoneNumber phone = new PhoneNumber("1-800-222-2222 ex 1234");
Console.WriteLine(phone); // output: (800) 222-2222 ext 1234

// Create an instance by parsing a phonetic phone number
PhoneNumber phone = new PhoneNumber("800 MY-TEST ex 1234", true);
Console.WriteLine(phone); // output: (800) MY-TEST ext 1234

// Check if a phone number is NANP valid
PhoneNumber phone = new PhoneNumber("(800) 222.2222");
Console.WriteLine("Is NANP valid? {0}", phone.IsNanpValid);

上述输出格式使用了默认格式输出(“P”格式 string),但输出可以自定义为几乎任何您想要的格式。下面是接受的格式 string 的概述

Token 描述
D 根据电话号码的值自动格式化。可能格式:c-a-x-s E, c-a-x-s, (a) x-s, (a) x-s E, x-s E, 和 x-s。
G “c-a-x-s e”的别名。
N 纯数字电话号码,没有特殊格式字符(与 caxs e 和/或 caxs 和/或 axs e 和/或 axs 和/或 xs e 和/或 xs 相同)。
P 语音表示,如果指定了语音 string 。如果没有语音 string,此格式 string 与“D”格式 string 相同。可能格式:c-a-p E, c-a-p, (a) p E, (a) p, p E, p, c-a-x-s E, c-a-x-s, (a) x-s E, (a) x-s, x-s E, 和 x-s。
F “P (x-s)”的别名,如果不存在语音 string 则为“D”。
c 此字符在格式 string 中出现的任何位置都将被替换为国家代码。
a 此字符在格式 string 中出现的任何位置都将被替换为 3 位 NPA 代码。
x 此字符在格式 string 中出现的任何位置都将被替换为 3 位 NXX 代码。
s 此字符在格式 string 中出现的任何位置都将被替换为 4 位站代码。
e 此字符在格式 string 中出现的任何位置都将被替换为分机代码。
E 此字符在格式 string 中出现的任何位置都将被替换为以“ext ”为前缀的分机代码。
p 此字符在格式 string 中出现的任何位置都将被替换为电话号码的语音表示。如果不存在语音 string,则此格式 string 与“x-s”相同。如果语音 string 不是七个字符,则使用 NPA 和 NXX 代码使其成为七个字符。

所有其他字符均保持不变。请注意,令牌区分大小写。

关注点

我最初使用正则表达式从 string 中解析电话号码,但在添加了越来越多的灵活性后,该表达式变得混乱且难以阅读,因此我选择了更具可读性和灵活性的、但稍慢的手动解析。所有解析工作都在 private 成员 _Parse() 中完成。

如果您想使用此结构来清理数据库中的电话号码并对其进行规范化,您可能需要编辑 _Parse 函数,放宽一些限制。在我清理数据库的几次中,我不得不注释掉检查语音字符数不超过七个(第 1306-1309 行)以及检查允许字符数组以成功清理所有数据库值(第 1317-1320 行)的部分。

该结构实现了 IComparableIFormattableISerializable 接口,并提供了 ==!=<><=>= 的运算符重载。我还为该结构提供了一个类型转换器,尽管我还没有完全测试它。

我没有提供项目/解决方案文件,因为我使用 MonoDevelop(是的,我在 Linux 环境中开发 .NET),我认为包含 MonoDevelop 项目/解决方案文件对大多数人来说都毫无用处。PhoneNumberTest.cs 文件只是一个简单的控制台应用程序,演示了如何使用该结构。代码使用说明都在 PhoneNumber.cs 文件的文档中。

待办事项

  1. 实现一个 ParseExact() 方法(类似于 DateTime.ParseExact() 方法)
  2. 实现一个 TryParseExact() 方法(类似于 DateTime.TryParseExact() 方法)
  3. 测试并确保该结构支持国际电话号码,并可能添加国际验证
  4. 改进分机解析,使其限制不那么严格

历史

  • 2008 年 12 月 24 日:初始发布
© . All rights reserved.