Google libphonenumber

Google 用于解析、格式化和验证国际电话号码的通用 Java、C++ 和 JavaScript 库。(Google's common Java, C++ and JavaScript library for parsing, formatting, and validating international phone numbers.)

  • Owner: google/libphonenumber
  • Platform: Android, Linux, Windows, Mac
  • License:: Apache License 2.0
  • Category::
  • Topic:
  • Like:
    7
      Compare:

Github stars Tracking Chart

这是什么?

Google 的通用 Java、C++ 和 JavaScript 库,用于解析、格式化和验证国际电话号码。 Java 版本针对智能手机的运行进行了优化,并从 4.0(Ice Cream Sandwich)开始被 Android 框架使用。

快速链接

功能亮点

  • 解析、格式化和验证世界上所有国家/地区的电话号码。
  • getNumberType -- 根据号码本身获取号码的类型;能够区分固定电话、移动电话、免费电话、高级费率、共享费用、VoIP、个人号码、UAN、寻呼机和语音邮件(只要可行)。
  • isNumberMatch -- 获得两个号码是否相同的置信度。
  • getExampleNumber 和 getExampleNumberForType -- 为所有国家/地区提供有效的示例号码,并可指定需要哪种类型的示例电话号码。
  • isPossibleNumber -- 通过使用长度信息快速猜测一个号码是否是一个可能的电话号码,比完整验证快得多。
  • isValidNumber -- 使用长度和前缀信息对一个区域的电话号码进行完全验证。
  • AsYouTypeFormatter -- 当用户输入每个数字时,即时格式化电话号码。
  • findNumbers -- 在文本中查找号码。
  • PhoneNumberOfflineGeocoder -- 提供与电话号码相关的地理信息。
  • PhoneNumberToCarrierMapper -- 提供与电话号码相关的运营商信息。
  • PhoneNumberToTimeZonesMapper -- 提供与电话号码相关的时区信息。

演示

Java

在 GitHub 发布后,Java 演示 的更新略有延迟。

最后一次演示更新:v8.12.9。

如果这个数字低于最新版本的版本号码,则说明我们处于两个版本之间,演示可能处于其中一个版本。

JavaScript

JavaScript 演示 可以在不同的标签下运行;这个链接将带您到 master 。【由于 RawGit 已被废弃,JS 演示链接无法使用。】TODO 在其他平台上托管。

Java代码

要在你的应用程序中包含 Java 代码,可以与 Maven 集成(请参阅 wiki ),或者从 Maven 仓库 下载最新的 jar 包。

Javadoc

Javadoc 会自动更新以反映最新的版本,网址为 http://javadoc.io/doc/com.googlecode.libphonenumber/libphonenumber/

版本控制和公告

我们通常会根据这些准则来选择版本号。

如果自上一个版本以来推送到主版本的任何变化与现有 libphonenumber API 的约定/规范不兼容,或者可能导致 libphonenumber(Java、C++ 或 JS)客户端不得不修改他们的代码来继续构建,我们就会发布一个主要版本。例如,如果上一个版本是 7.7.3,新的版本就是 8.0.0。

如果这些变化使客户端能够更新他们的代码以利用新的功能,并且如果客户端不得不在该版本被标记为 "bad" 的情况下回滚这些变化,我们将发布一个次要版本。例如,我们会从 7.7.3 到 7.8.0。

否则,包括仅当版本包含 元数据 变化时,我们会发布次小版本,例如 7.7.3 至 7.7.4。

有时, 我们会对代码或元数据进行内部修改, 虽然这些修改不会影响到客户端的兼容性, 但却会影响到库的移植者的兼容性。对于这样的改动,我们会在 libphonenumber-discUSS 中发布公告。这样的改动不会反映在版本号中,如果没有其他改动,我们会发布一个次小版本。

想得到新版本的通知吗?在一年中的大部分时间里,除了节假日和情有可原的情况,我们每两周发布一次。我们会更新发布标签并记录详细的发布说明。我们也会在每次发布时向 libphonenumber-discuss 发送公告 -- 讨论每个版本。

快速示例

假设你有一个代表瑞士电话号码的字符串。这就是你如何将它解析/归一化为一个 PhoneNumber 对象的方式:

String swissNumberStr = "044 668 18 00";
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
  PhoneNumber swissNumberProto = phoneUtil.parse(swissNumberStr, "CH");
} catch (NumberParseException e) {
  System.err.println("NumberParseException was thrown: " + e.toString());
}

此时, swissNumberProto 包含:

{
  “country_code”:41,
  “national_number”:446681800
}

PhoneNumber 是一个最初由 phonenumber.proto 自动生成的类,为了提高效率,它做了必要的修改。关于每个字段的详细含义,请参考 resources/phonenumber.proto。 现在让我们验证一下这个号码是否有效:

 boolean isValid = phoneUtil.isValidNumber(swissNumberProto); //returns true

格式化方法支持的格式有几种,如下所示:

//Produces "+41 44 668 18 00"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.INTERNATIONAL));
//Produces "044 668 18 00"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.NATIONAL));
//Produces "+41446681800"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.E164));

您还可以选择按照从其他国家/地区拨打的方式格式化数字:

 //Produces "011 41 44 668 1800", the number when it is dialed in the United States.
System.out.println(phoneUtil.formatOutOfCountryCallingNumber(swissNumberProto, "US"));

输入电话号码时的格式化

PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("US");
System.out.println(formatter.inputDigit('6'));  //Outputs "6"
...  //Input more digits
System.out.println(formatter.inputDigit('3'));  //Now outputs "650 253"

电话号码的地理编码

PhoneNumberOfflineGeocoder geocoder = PhoneNumberOfflineGeocoder.getInstance();
//Outputs "Zurich"
System.out.println(geocoder.getDescriptionForNumber(swissNumberProto, Locale.ENGLISH));
//Outputs "Zürich"
System.out.println(geocoder.getDescriptionForNumber(swissNumberProto, Locale.GERMAN));
//Outputs "Zurigo"
System.out.println(geocoder.getDescriptionForNumber(swissNumberProto, Locale.ITALIAN));

将电话号码映射到原运营商

警告:我们不提供有关电话号码的当前运营商的数据,只提供分配到相应范围的原运营商的数据。阅读关于号码可携性的内容。了解号码可携性的内容。

PhoneNumber swissMobileNumber =
    new PhoneNumber().setCountryCode(41).setNationalNumber(798765432L);
PhoneNumberToCarrierMapper carrierMapper = PhoneNumberToCarrierMapper.getInstance();
//Outputs "Swisscom"
System.out.println(carrierMapper.getNameForNumber(swissMobileNumber, Locale.ENGLISH));

有关如何使用该库的更多示例,可以在单元测试中找到。

第三方移植

我们知道有几个电话号码库的第三方移植库。我们在这里分享他们,是因为他们或许对开发者有用。

不过,我们强调这些移植是由 libphonenumber 项目之外的开发者完成的。我们不评估它们的质量,也不影响它们的维护过程。

我们自己版本的替代品:

  • Android-optimized:我们的 Java 版本从 Class#getResourcesAsStream 加载元数据,并要求 Android 应用程序遵循 Android 加载的最佳实践,即重新打包元数据并自己从 AssetManager#open() 加载(常见问题)。如果您不想这样做,请查看 https://github.com/MichaelRocks/libphonenumber-android 的移植版,它会重新打包元数据并使用 AssetManager#open(),并且可以依赖它,而不需要客户端进行那些特定的加载优化。
  • Javascript:如果你不想使用我们的版本,因为它依赖于Closure,还有其他一些选择,其中包括 https://github.com/halt-hammerzeit/libphonenumber-js -- 一个简约的重写,大小约 110 KB;以及 https://github.com/seegno/google-libphonenumber -- 一个可通过 npm 安装的原版未修改库的浏览器兼容包装器,它打包了 Google Closure 库,大小约 420 KB。

(Second edition: vz revised at 2020.08.30)

Overview

Name With Ownergoogle/libphonenumber
Primary LanguageC++
Program languageCMake (Language Count: 9)
PlatformAndroid, Linux, Windows, Mac
License:Apache License 2.0
Release Count213
Last Release Namev8.13.35 (Posted on 2024-04-18 08:09:18)
First Release Namelibphonenumber-7.0.2 (Posted on 2015-01-19 12:46:32)
Created At2014-12-03 18:02:17
Pushed At2024-04-18 09:55:35
Last Commit At2024-04-18 15:25:35
Stargazers Count16k
Watchers Count391
Fork Count2k
Commits Count2.2k
Has Issues Enabled
Issues Count0
Issue Open Count0
Pull Requests Count1240
Pull Requests Open Count107
Pull Requests Close Count643
Has Wiki Enabled
Is Archived
Is Fork
Is Locked
Is Mirror
Is Private

What is it?

Google's common Java, C++ and JavaScript library for parsing, formatting, and
validating international phone numbers. The Java version is optimized for
running on smartphones, and is used by the Android framework since 4.0 (Ice
Cream Sandwich).

Quick links

Highlights of functionality

  • Parsing, formatting, and validating phone numbers for all countries/regions
    of the world.
  • getNumberType - gets the type of the number based on the number itself;
    able to distinguish Fixed-line, Mobile, Toll-free, Premium Rate, Shared
    Cost, VoIP, Personal Numbers, UAN, Pager, and Voicemail (whenever feasible).
  • isNumberMatch - gets a confidence level on whether two numbers could be
    the same.
  • getExampleNumber and getExampleNumberForType - provide valid example
    numbers for all countries/regions, with the option of specifying which type
    of example phone number is needed.
  • isPossibleNumber - quickly guesses whether a number is a possible
    phone number by using only the length information, much faster than a full
    validation.
  • isValidNumber - full validation of a phone number for a region using
    length and prefix information.
  • AsYouTypeFormatter - formats phone numbers on-the-fly when users enter
    each digit.
  • findNumbers - finds numbers in text.
  • PhoneNumberOfflineGeocoder - provides geographical information related to
    a phone number.
  • PhoneNumberToCarrierMapper - provides carrier information related to a
    phone number.
  • PhoneNumberToTimeZonesMapper - provides timezone information related to a
    phone number.

Demo

Java

The Java demo is updated with a slight
delay after the GitHub release.

Last demo update: v8.11.3.

If this number is lower than the latest release's version
number
, we are between
releases and the demo may be at either version.

JavaScript

The JavaScript
demo

may be run at various tags; this link will take you to master.

Java code

To include the Java code in your application, either integrate with Maven (see
wiki) or download the latest
jars from the Maven
repository
.

Javadoc

Javadoc is automatically updated to reflect the latest release at
https://javadoc.io/doc/com.googlecode.libphonenumber/libphonenumber/.

Versioning and Announcements

We generally choose the release number following these guidelines.

If any of the changes pushed to master since the last release are incompatible
with the intent / specification of an existing libphonenumber API or may cause
libphonenumber (Java, C++, or JS) clients to have to change their code to keep
building, we publish a major release. For example, if the last release were
7.7.3, the new one would be 8.0.0.

If any of those changes enable clients to update their code to take advantage
of new functionality, and if clients would have to roll-back these changes in
the event that the release was marked as "bad", we publish a minor release. For
example, we'd go from 7.7.3 to 7.8.0.

Otherwise, including when a release contains only
metadata changes, we publish a sub-minor release,
e.g. 7.7.3 to 7.7.4.

Sometimes we make internal changes to the code or metadata that, while not
affecting compatibility for clients, could affect compatibility for porters
of the library. For such changes we make announcements to
libphonenumber-discuss. Such changes
are not reflected in the version number, and we would publish a sub-minor
release if there were no other changes.

Want to get notified of new releases? During most of the year, excepting
holidays and extenuating circumstances, we release fortnightly. We update
release tags and
document detailed release notes.
We also send an announcement to libphonenumber-discuss for every
release.

Quick Examples

Let's say you have a string representing a phone number from Switzerland. This
is how you parse/normalize it into a PhoneNumber object:

String swissNumberStr = "044 668 18 00";
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
  PhoneNumber swissNumberProto = phoneUtil.parse(swissNumberStr, "CH");
} catch (NumberParseException e) {
  System.err.println("NumberParseException was thrown: " + e.toString());
}

At this point, swissNumberProto contains:

{
  "country_code": 41,
  "national_number": 446681800
}

PhoneNumber is a class that was originally auto-generated from
phonenumber.proto with necessary modifications for efficiency. For details on
the meaning of each field, refer to resources/phonenumber.proto.

Now let us validate whether the number is valid:

boolean isValid = phoneUtil.isValidNumber(swissNumberProto); // returns true

There are a few formats supported by the formatting method, as illustrated
below:

// Produces "+41 44 668 18 00"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.INTERNATIONAL));
// Produces "044 668 18 00"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.NATIONAL));
// Produces "+41446681800"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.E164));

You could also choose to format the number in the way it is dialed from another
country:

// Produces "011 41 44 668 1800", the number when it is dialed in the United States.
System.out.println(phoneUtil.formatOutOfCountryCallingNumber(swissNumberProto, "US"));

Formatting Phone Numbers 'as you type'

PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("US");
System.out.println(formatter.inputDigit('6'));  // Outputs "6"
...  // Input more digits
System.out.println(formatter.inputDigit('3'));  // Now outputs "650 253"

Geocoding Phone Numbers

PhoneNumberOfflineGeocoder geocoder = PhoneNumberOfflineGeocoder.getInstance();
// Outputs "Zurich"
System.out.println(geocoder.getDescriptionForNumber(swissNumberProto, Locale.ENGLISH));
// Outputs "Zürich"
System.out.println(geocoder.getDescriptionForNumber(swissNumberProto, Locale.GERMAN));
// Outputs "Zurigo"
System.out.println(geocoder.getDescriptionForNumber(swissNumberProto, Locale.ITALIAN));

Mapping Phone Numbers to original carriers

Caveat: We do not provide data about the current carrier of a phone number, only
the original carrier who is assigned the corresponding range. Read about number
portability
.

PhoneNumber swissMobileNumber =
    new PhoneNumber().setCountryCode(41).setNationalNumber(798765432L);
PhoneNumberToCarrierMapper carrierMapper = PhoneNumberToCarrierMapper.getInstance();
// Outputs "Swisscom"
System.out.println(carrierMapper.getNameForNumber(swissMobileNumber, Locale.ENGLISH));

More examples on how to use the library can be found in the unit
tests
.

Third-party Ports

Several third-party ports of the phone number library are known to us. We share
them here in case they're useful for developers.

However, we emphasize that these ports are by developers outside the
libphonenumber project. We do not evaluate their quality or influence their
maintenance processes.

Alternatives to our own versions:

  • Android-optimized: Our Java version loads the metadata from
    Class#getResourcesAsStream and asks that Android apps follow the Android
    loading best practices of repackaging the metadata and loading from
    AssetManager#open() themselves
    (FAQ).
    If you don't want to do this, check out the port at
    https://github.com/MichaelRocks/libphonenumber-android, which does repackage
    the metadata and use AssetManager#open(), and may be depended on without
    needing those specific loading optimizations from clients.
  • Javascript: If you don't want to use our version, which depends on Closure,
    there are several other options, including
    https://github.com/catamphetamine/libphonenumber-js - a stripped-down
    rewrite, about 110 KB in size - and
    https://github.com/seegno/google-libphonenumber - a browserify-compatible
    wrapper around the original unmodified library installable via npm, which
    packs the Google Closure library, about 420 KB in size.
To the top