如何将手机号码分成国家代码、地区代码和本地号码?

22

如何将手机号码拆分成国家代码、地区代码和本地号码?

例如:+919567123456 拆分后

国家代码 = 91

地区代码 = 9567

本地号码 = 123456


@Vivart 最好的方法是使用子字符串。 - ant
字符串 country_code="91"; 字符串 area_code="9567"; 字符串 local_number="123456"; 说真的,能提供更多信息吗?例如区号总是4位数? - Federico klez Culloca
1
@Vivart,你使用的是印度的例子,移动电话的国家代码后面没有区号。它始终是一个10位数的手机号码。 - JoseK
@josek 印度号码的格式始终为国家代码 + MSC代码 + 本地号码。如果您有MSC代码列表,您可以知道9567 MSC代码属于喀拉拉邦,运营商是Airtel。 - Vivart
区号不适用于丹麦移动电话号码。 - Thorbjørn Ravn Andersen
7个回答

54

3
但我没有看到任何显示区号的方法。我有什么遗漏吗? - Arya
区号在C代码中被引用,但在Java代码中似乎存在国家代码与区号混淆的情况。我无法看到任何地区。 - ben26941

26

使用简单的算法无法解析电话号码,你需要使用填充有每个国家规则的数据表 - 因为每个国家对其电话号码进行不同的分隔。

国家代码相对容易,只需使用维基百科中的国际电话区号文章中的数据,并构建所有唯一国家代码的表格。每个国家都有一个唯一的前缀,所以这很容易。

但是,您需要查找每个要支持的国家的规则并使用每个国家的规则提取区号。


6
正如许多人所说,您无法通过简单的字符串匹配来实现此目标。国家和区号的长度都不固定。
我们过去曾经维护了一个类似以下结构的表格:
+------------+---------+-------+--------------+ |country_code|area_code|country|area | +------------+---------+-------+--------------+ |44 |1634 |UK |Medway | |44 |20 |UK |London | |964 |23 |Iraq |Wasit (Al Kut)| |964 |2412 |Iraq |Unreal | +------------+---------+-------+--------------+
然后我们计算了最大的区号和国家代码的长度,并从最大长度开始逐步缩小字符串并检查是否匹配。
因此,对于给定的号码441634666788,
我们将从子字符串[1,7](7是最长的国家/地区代码组合的长度)开始搜索,没有找到匹配项,然后移动到[1,6]并找到了UK / Medway的匹配项。
这种方法效率不高,但可以解决问题。
编辑
您也可以尝试像这样的方法,但是您需要使用完整数据集进行测试,或者甚至将其拆分为单独的国家和区号选择,因为它可能在您选择的数据库中性能不佳。
 DECLARE @area_codes TABLE
(
    country_code VARCHAR(10),
    area_code VARCHAR(10),
    country VARCHAR(20),
    area VARCHAR(20),
    match_string VARCHAR(MAX),
    match_length INTEGER
)

INSERT INTO @area_codes VALUES ('44','1382','UK','Dundee', '441382%', 6)
INSERT INTO @area_codes VALUES ('44','1386','UK','Evesham', '441386%', 6)
INSERT INTO @area_codes VALUES ('44', '1', 'UK', 'Geographic numbers', '441%', 3)

DECLARE @number VARCHAR(MAX)
SET @number = '441386111111'

SELECT TOP 1 * 
FROM @area_codes 
WHERE @number LIKE match_string
ORDER BY match_length DESC

你需要通过触发器来维护match_string和match_length字段,注意处理空的区号并在match_string列上建立索引。

4

我认为你需要类似国家和地区代码的词典,因为两者长度可能不同。例如美国+1,德国+49,甚至是+6723。区号也是一样的。


4
答案很大程度上取决于国家。没有“通用”的规定说“这是国家代码,这是区号,这是本地号码”。唯一可以普遍获取的信息是国家代码(即使那也可能有1-4位数);然后您需要查阅特定国家的规则集。
例如(比如,“在给定的国家中有许多不同的电话号码,但它们都遵循相同的格式”):
  • +420123456789是捷克共和国(国家代码+420)的虚假号码,其余部分是本地号码(一些国家使用未分割的寻址空间,尽管您可以从本地号码的前1-4位推断出一些数据(例如,“+420800”是免费电话号码)。因此,解析此号码的唯一有用方法是将其分为两个部分,+420 123456789
  • +18005551234是美国的(可能也是虚假的)号码;根据北美编号计划, +1是国家代码,800是区号(免费电话号码),555是交换机代码,1234是本地号码。然后,您可以将该号码解析为四个部分,+1 800 555 1234

@Pacerier:我查阅了美国的规则集:http://en.wikipedia.org/wiki/North_American_Numbering_Plan#Current_system 。它说,基本上,“+1是国际呼叫代码,接下来的三个数字是区号,接下来的三个数字是交换机代码,剩余的四个数字是用户号码”。因此,美国电话号码中第5-7位的任何内容都是交换机代码。当然,这个规则集对于每个国家可能都不同。 - Piskvor left the building
不是吗?即使在美国本土,由于周围有这么多公司,它也不能有所不同吗? - Pacerier
@Pacerier:好的,你看了那个链接吗?那我给你引用一下:“允许范围:第一个数字为[2-9],第二和第三个数字为[0-9]。”当然,可能的交换号码不仅仅是字面上的“555”,我只是用这个数字作为示例 - Piskvor left the building

2

1
一个非常复杂的问题。首先,你需要确定国家代码。根据国家代码,其余部分必须被拆分为区号和本地号码。但是三个部分中没有一个有固定长度,既不是整个号码,也不是区号和本地部分的组合!
例子:4930123456789
  • 49是德国的国家代码
  • 30是柏林的区号
  • 123456789是柏林的本地号码(没有真实的号码)
例子:493328123456
  • 49是德国的国家代码
  • 3328是泰尔托的区号
  • 123456是泰尔托的本地号码(没有真实的号码)
例子:34971123456
  • 34是西班牙的国家代码
  • 971是马略卡岛的区号
  • 123456是马略卡岛上的本地号码(没有真实的号码)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接