【问题标题】:Extract code country from phone number [libphonenumber]从电话号码中提取代码国家 [libphonenumber]
【发布时间】:2013-05-24 10:54:59
【问题描述】:

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

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

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

但我找不到在不知道国家/地区的情况下解析字符串的方法。

【问题讨论】:

  • 第一个链接是基于电话国家代码的。但就我而言,我可以有一个字符串,它是一个带有英文电话的法国电话号码。因此,如果我检索当前语言环境,我将有“EN”,但我的字符串将是法国国家/地区代码
  • @Simon,我知道这是一篇旧帖子,但我不认为你提到的两个问题是重复的。干杯。

标签: android libphonenumber


【解决方案1】:

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

【讨论】:

【解决方案2】:

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

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

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

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

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

希望对你有帮助

【讨论】:

  • internationalFormatPhoneNumber DataType 和 phoneUtil 是什么
  • givenPhoneNumber 参数不是字符串,它必须是已经解析的电话号码,您需要生成默认区域
  • @GilSH 是 givenPhoneNumber 不是 String,它是 PhoneNumber 对象。
  • 这个答案对我有帮助
  • 什么是给定的PhoneNumber??
【解决方案3】:

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

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

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());
}

【讨论】:

  • 这个 wackadoo 疯狂的库非常棒,比 android 中包含的 PhoneNumberUtils 库好十亿倍
  • @Shweta 如果您有任何问题,请在 SO 上的新线程上发布它
  • @aat 好的,但你的答案不正确,如果不提供任何国家/地区ISOCode,此代码将不会执行
  • @Schweta defaultRegion 参数应为空: defaultRegion - ISO 3166-1 两个字母的区域代码,表示我们期望数字来自的区域。这仅在被解析的数字不是以国际格式编写的情况下使用。在这种情况下,该号码的 country_code 将存储为提供的默认区域的代码。如果保证号码以“+”开头,后跟国家/地区呼叫代码,则可以提供“ZZ”或 null。
  • 如果我需要将电话簿中的电话号码解析为 E164 格式并且电话的区域设置可能发生变化(例如,当电话用户前往其他国家/地区时),我该怎么办。我也知道大多数数字都不是格式+.....
【解决方案4】:

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

获取所有可用国家/地区代码的列表,维基百科可以在这里提供帮助: https://en.wikipedia.org/wiki/List_of_country_calling_codes

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

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

【讨论】:

  • 因为这条评论,我对此投了反对票:“这是一个答案,如何在不使用第三方库的情况下找到国家/地区呼叫代码(就像真正的开发人员所做的那样):”你为什么认为软件取得进展?这是因为人们不必每次都重新发明轮子。真正的开发人员使用第三方库是因为他/她很聪明。
  • 您的个人意见不会使我的答案不正确,是吗?事实上,这是迄今为止唯一正确且无懈可击的答案……是的,它不需要任何 3rd 方软件即可工作。如果您坚持使用 3rd 方库,欢迎购买我的解决方案。
  • 更新图书馆比不断去维基百科页面查看国家/地区呼叫代码列表是否已更改更容易。
  • @Unobic 对不起,伙计。他们不应该因为对 Stackoverflow 的个人意见而投票。我在搜索时正在寻找您的答案。所以感谢我。至少有我的支持。
【解决方案5】:

根据上面发布的一个答案,我有一个方便的帮助方法来处理这个问题:

进口:

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) {
            ""
        }
    }

【讨论】:

    【解决方案6】:

    使用如下所示的 try catch 块:

    try { 
    
    const phoneNumber = this.phoneUtil.parseAndKeepRawInput(value, this.countryCode);
    
    }catch(e){}
    

    【讨论】:

      【解决方案7】:

      这是一种无需使用 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;
      }
      

      其余代码(世界各国的数字信息、测试代码……)太大,无法在此处发布,但可以在 Github 上找到: https://github.com/PeterHuberSg/WpfWindowsLib/blob/master/WpfWindowsLib/CountryCode.cs

      该代码是 WPF 文本框的一部分,该库还包含用于电子邮件地址等的其他控件。更详细的说明参见 CodeProject:International Phone Number Validation Explained in Detail

      【讨论】:

        猜你喜欢
        • 2021-04-25
        • 1970-01-01
        • 2017-04-09
        • 2017-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多