从电话号码[libphonenumber]中提取代码国家/地区


80

我有一个像这样的字符串:+33123456789(法国电话号码)。我想在不知道国家的情况下提取国家代码(+33)。例如,如果我有另一个国家的电话,它应该可以工作。我使用Google库https://code.google.com/p/libphonenumber/

如果我知道国家/地区,这很酷,我可以找到国家/地区代码:

PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
int countryCode = phoneUtil.getCountryCodeForRegion(locale.getCountry());

但是我不知道如何在不了解国家的情况下解析字符串。




1
第一条链接基于电话国家/地区代码。但就我而言,我可以输入一个字符串,该字符串是法语电话号码和英语电话。因此,如果我检索当前的语言环境,我将带有“ EN”,但是我的字符串将是法国的国家代码
mrroboaat

Answers:


124

好的,所以我加入了libphonenumber的Google组(https://groups.google.com/forum/?hl=zh-CN&fromgroups#!forum/libphonenumber-discuss),并提出了一个问题。

如果我的电话号码以“ +”开头,则无需在参数中设置国家/地区。这是一个例子:

PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
    // phone must begin with '+'
    PhoneNumber numberProto = phoneUtil.parse(phone, "");
    int countryCode = numberProto.getCountryCode();
} catch (NumberParseException e) {
    System.err.println("NumberParseException was thrown: " + e.toString());
}

4
这个疯狂的wackadoo库令人惊叹,比sandroid中包含的PhoneNumberUtil库好十亿倍
Aphex 2014年

@aat您能告诉我如何在不使用(phoneUtil.parse(phone,“”);)中的countryISOCode的情况下如何工作吗?请回答
Ash

1
@Shweta如果您有任何疑问,请将其发布在SO的新主题上
mrroboaat 2014年

1
@aat好的,但是您的答案不正确,没有提供任何国家/地区代码将无法执行此代码
Ash,

3
@Schweta defaultRegion参数应该为null:defaultRegion-ISO 3166-1两个字母的区域代码,表示我们希望该数字来自的区域。仅当要解析的数字不是以国际格式书写时,才使用此选项。在这种情况下,号码的country_code将作为提供的默认区域的国家/地区代码存储。如果保证数字以“ +”开头,然后是国家/地区代码,则可以提供“ ZZ”或空值。
xnagyg,2015年

3

在这里,您可以将电话号码另存为国际格式的电话号码

internationalFormatPhoneNumber = phoneUtil.format(givenPhoneNumber, PhoneNumberFormat.INTERNATIONAL);

它以国际格式返回电话号码+94 71 560 4888

所以现在我得到了国家代码

String countryCode = internationalFormatPhoneNumber.substring(0,internationalFormatPhoneNumber.indexOf('')).replace('+', ' ').trim();

希望这能够帮到你


1
什么是internationalFormatPhoneNumberDataType和phoneUtil
Kartheek的

1
namedPhoneNumber参数不是字符串,必须是已解析的电话号码(您需要默认区域才能生成)
Gil SH 2014年

@GilSH是GivenPhoneNumber不是String,它是PhoneNumber对象。
Thilina Rubasingha 2014年

1
这个答案对我有帮助
luttu android 2014年

给定的电话号码是什么?
TharakaNirmana '16

3

根据上面发布的一个答案,我保留了一个方便的助手方法来解决此问题:

进口:

import com.google.i18n.phonenumbers.NumberParseException
import com.google.i18n.phonenumbers.PhoneNumberUtil

功能:

    fun parseCountryCode( phoneNumberStr: String?): String {
        val phoneUtil = PhoneNumberUtil.getInstance()
        return try {
            // phone must begin with '+'
            val numberProto = phoneUtil.parse(phoneNumberStr, "")
            numberProto.countryCode.toString()
        } catch (e: NumberParseException) {
            ""
        }
    }

0

使用如下所示的try catch块:

try { 

const phoneNumber = this.phoneUtil.parseAndKeepRawInput(value, this.countryCode);

}catch(e){}

0

这是一种无需使用Google图书馆即可根据国际电话号码获得国家/地区的解决方案。

首先让我解释一下为什么很难弄清楚这个国家。少数国家的国家/地区代码是1位数,2、3或4位数。那将很简单。但是国家代码1不仅用于美国,而且还用于加拿大和一些较小的地方:

1339美国
1340维尔京群岛(加勒比海群岛)
1341美国
1342未使用
1343加拿大

数字2..4决定是美国还是加拿大还是……没有简单的方法可以弄清楚这个国家,例如第一个xxx是加拿大,其余的是美国。

对于我的代码,我定义了一个类,用于保存数字位数的信息:

public class DigitInfo {
  public char Digit;
  public Country? Country;
  public DigitInfo?[]? Digits;
}

第一个数组为数字中的第一个数字保存DigitInfos。第二个数字用作DigitInfo.Digits的索引。一个人沿着该Digits链向下移动,直到Digits为空。如果定义了Country(即不为null),则返回该值,否则将返回先前定义的任何Country:

country code 1: byPhone[1].Country is US  
country code 1236: byPhone[1].Digits[2].Digits[3].Digits[6].Country is Canada  
country code 1235: byPhone[1].Digits[2].Digits[3].Digits[5].Country is null. Since   
                   byPhone[1].Country is US, also 1235 is US, because no other   
                   country was found in the later digits

这是根据电话号码返回国家/地区的方法:

/// <summary>
/// Returns the Country based on an international dialing code.
/// </summary>
public static Country? GetCountry(ReadOnlySpan<char> phoneNumber) {
  if (phoneNumber.Length==0) return null;

  var isFirstDigit = true;
  DigitInfo? digitInfo = null;
  Country? country = null;
  foreach (var digitChar in phoneNumber) {
    var digitIndex = digitChar - '0';
    if (isFirstDigit) {
      isFirstDigit = false;
      digitInfo = ByPhone[digitIndex];
    } else {
      if (digitInfo!.Digits is null) return country;

      digitInfo = digitInfo.Digits[digitIndex];
    }
    if (digitInfo is null) return country;

    country = digitInfo.Country??country;
  }
  return country;
}

其余代码(适用于世界每个国家的digitInfos,测试代码等)太大,无法在此处发布,但可以在Github上找到:https : //github.com/PeterHuberSg/WpfWindowsLib/blob /master/WpfWindowsLib/CountryCode.cs

该代码是WPF TextBox的一部分,该库还包含其他用于电子邮件地址的控件,等等。有关详细信息,请参见CodeProject:国际电话号码验证详细解释


-4

如果包含电话号码的字符串始终以这种方式开头(+33或其他国家/地区代码),则应使用正则表达式进行解析并获取国家/地区代码,然后使用库获取与该号码相关联的国家/地区。


它存在许多不同的国家/地区代码:http
mrroboaat

-23

这是一个答案,如何在不使用第三方库的情况下(如真正的开发人员那样)查找国家/地区代码:

获取所有可用国家代码的列表,Wikipedia可以在此处提供帮助:https : //en.wikipedia.org/wiki/List_of_country_calling_codes

以树结构解析数据,其中每个数字都是一个分支。

遍历您的树,直到您到达最后一个分支-这就是您的国家/地区代码。


23
我之所以对此表示反对,是因为这样的评论:“这是一个无需使用第三方库就可以找到拨打国家代码的答案(就像真正的开发商一样):”为什么您认为软件取得了进步?这是因为人们不必每次都重新发明轮子。REAL开发人员使用第三方库是因为他/她很聪明。
卡尔·

2
您的个人意见不会使我的答案不正确,对吗?实际上,这是到目前为止唯一正确且防弹的答案……是的,它不需要任何第三方软件即可工作。如果您坚持使用第三方库,欢迎购买我的解决方案。
Unobic

2
与连续访问Wikipedia页面以检查国家/地区电话代码列表是否已更改相比,更新图书馆要容易得多。
Flimm

@Unobic对不起的人。他们不应因为对Stackoverflow的个人观点而投票。搜索时,我正在寻找您的答案。所以,谢谢我。至少要我投票。
Ybrin
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.