Java电话号码格式API

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/487906/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:16:37  来源:igfitidea点击:

Java phone number format API

java

提问by Chase Seibert

I have a database with millions of phone numbers with free-for-all formatting. Ie, the UI does not enforce any constraints and the users are typing in whatever they want.

我有一个数据库,里面有数百万个电话号码,所有格式都是免费的。即,用户界面不强制执行任何约束,用户输入他们想要的任何内容。

What I'm looking for is a Java API that can make a best-effort to convert these into a consistent format. Ideally, the API would take the free text value and a country code and produce a valid international phone number or throw an exception.

我正在寻找的是一个 Java API,它可以尽最大努力将这些转换为一致的格式。理想情况下,API 将采用自由文本值和国家/地区代码并生成有效的国际电话号码或抛出异常。

For example, a phone number in the system might look like any of the following:

例如,系统中的电话号码可能如下所示:

(555) 478-1123
555-478-1123    
555.478.1123
5554781123

Given the country of US, the API would produce the value "+1 (555) 478-1123" for all these. The exact format does not matter, as long as it's consistent.

给定美国国家/地区,API 将为所有这些生成值“+1 (555) 478-1123”。确切的格式并不重要,只要它是一致的。

There are also numbers in the system without area codes, such as "478-1123". In that case, I would expect a NoAreaCodeException, or something similar.

系统中也有没有区号的号码,比如“478-1123”。在这种情况下,我会期待 NoAreaCodeException 或类似的东西。

There could also be data such as "abc", which should also throw exceptions.

也可能有诸如“abc”之类的数据,它也应该抛出异常。

Of course, there are countless variations of the examples I have posted, as well as the enormous complication of international phone numbers, which have quite complicated validation rules. This is why I would not consider rolling my own.

当然,我发布的示例有无数变体,以及国际电话号码的巨大复杂性,它们具有非常复杂的验证规则。这就是为什么我不会考虑自己滚动。

Has anyone seen such an API?

有人见过这样的API吗?

采纳答案by Bill the Lizard

You could write your own (for US phone # format):

您可以编写自己的(对于美国电话号码格式):

  • Strip any non-numeric characters from the string
  • Check that the remaining string is ten characters long
  • Put parentheses around the first three characters and a dash between the sixth and seventh character.
  • Prepend "+1 " to the string
  • 从字符串中去除任何非数字字符
  • 检查剩余的字符串是否为十个字符长
  • 在前三个字符周围加上括号,在第六个和第七个字符之间加上一个破折号。
  • 在字符串前加上“+1”



Update:

更新:

Google recently released libphonenumberfor parsing, formatting, storing and validating international phone numbers.

谷歌最近发布了用于解析、格式化、存储和验证国际电话号码的libphonenumber

回答by Olvagor

I don't know of such an API but it looks like could be done by using regular expressions. Probably you can't convert all numbers to a valid format but most of them.

我不知道这样的 API,但看起来可以通过使用正则表达式来完成。可能您无法将所有数字转换为有效格式,但大多数都是如此。

回答by Zach Scrivena

There are commercial programs that format and validate international telephone numbers, like this onewhich even checks for valid area codes in some countries. For North America, the NANPAprovides some resourcesfor validating area codes.

有一些商业程序可以格式化和验证国际电话号码,比如这个甚至可以检查某些国家/地区的有效区号的程序。对于北美,NANPA提供了一些用于验证区号的资源

回答by Michael Borgwardt

I don't think there is a way of recognizing the lack of an area code unless your numbers are all from one country (presumably the USA), as each country has its own rules for things like area codes.

我不认为有一种方法可以识别缺少区号,除非您的号码都来自一个国家(大概是美国),因为每个国家/地区都有自己的区号规则。

I'd start looking for detailed information here, here, and here- if there are APIs to handle it (in Java or otherwise), they might be linked to there as well.

我会在这里这里这里开始寻找详细信息——如果有 API 来处理它(Java 或其他方式),它们也可能链接到那里。

回答by mafu

The best i found was javax.telephony, to be found here: http://java.sun.com/products/javaphone/

我发现的最好的是javax.telephony,可以在这里找到:http: //java.sun.com/products/javaphone/

It has an Address class, but sadly that class did not solve your problem :( Well, maybe you can find a solution by digging deeper into it.

它有一个 Address 类,但遗憾的是该类并没有解决您的问题 :( 好吧,也许您可​​以通过深入研究来找到解决方案。

Apart of that, my first idea was to use regex. However, that seems to be a kind of bad solution to this specific problem.

除此之外,我的第一个想法是使用正则表达式。然而,这似乎是针对这个特定问题的一种糟糕的解决方案。

回答by g1smd

You could try this Java phone number formatting library https://github.com/googlei18n/libphonenumber

你可以试试这个 Java 电话号码格式库https://github.com/googlei18n/libphonenumber

It has data for hundreds of countries and formats.

它拥有数百个国家和格式的数据。

回答by g1smd

The recent versions of http://code.google.com/p/libphonenumber/have added metadata for many new countries and added a lot more detail for some of the countries previously listed.

http://code.google.com/p/libphonenumber/的最新版本为许多新国家/地区添加了元数据,并为之前列出的一些国家/地区添加了更多详细信息。

The current source code version is r74 and the .jar file is at version 2.6. Previous .jar files were compiled for Java 1.6, but as of libphonenumber version 2.5.1 onwards they are now compiled for Java 1.5 and above.

当前源代码版本为 r74,.jar 文件版本为 2.6。以前的 .jar 文件是为 Java 1.6 编译的,但从 libphonenumber 2.5.1 版开始,它们现在是为 Java 1.5 及更高版本编译的。

Don't forget there is also a direct port of the code to JavaScript. It can be found in the source code tree at http://code.google.com/p/libphonenumber/source/browse/#svn%2Ftrunk%2Fjavascript

不要忘记还有一个直接将代码移植到 JavaScript 的端口。它可以在http://code.google.com/p/libphonenumber/source/browse/#svn%2Ftrunk%2Fjavascript的源代码树中找到

Bug reports are welcome. Updates to metadata are actively encouraged, as even the official government-published area code lists for many countries are either incomplete or out of date.

欢迎报告错误。积极鼓励更新元数据,因为即使是许多国家的官方政府发布的区号列表也不完整或已过时。

回答by Masaru Tomimitsu

For French number which look like "01 44 55 66 77", we can use the following logic.

对于看起来像“01 44 55 66 77”的法语数字,我们可以使用以下逻辑。

DecimalFormatSymbols dfs = new DecimalFormatSymbols();
dfs.setGroupingSeparator(' ');  // sometimes '.' is used
DecimalFormat decfmt = new DecimalFormat("0,0", dfs);  // enable grouping
decfmt.setMinimumIntegerDigits(10);  // we always have 10 digits
decfmt.setGroupingSize(2);  // necessary in order to group digits by 2 orders
System.out.println(decfmt.format(144556677));  // outputs "01 44 55 66 77"

Once this could be done, with google's phone number API the others mentioned, we can parse these sequences easily and reformat them into other forms such as "+33 1 44 55 66 77" like the following:

一旦可以完成,使用其他人提到的谷歌电话号码 API,我们可以轻松解析这些序列并将它们重新格式化为其他形式,例如“+33 1 44 55 66 77”,如下所示:

Iterable<PhoneNumberMatch> numbers = PhoneNumberUtil.getInstance().findNumbers(textWithPhoneNums, "FR");
for(Iterator<PhoneNumberMatch> iterator = numbers.iterator(); iterator.hasNext(); ){
    PhoneNumberMatch pnm = iterator.next();
    PhoneNumber number = pnm.number();
    System.out.println(PhoneNumberUtil.getInstance().formatOutOfCountryCallingNumber(number, null));
}

回答by Paschalis

Simple regex parser

简单的正则表达式解析器

/**
 * @param pPhoneNumber
 * @return true if the phone number is correct
 */
private boolean isPhoneNumberCorrect(String pPhoneNumber) {

    Pattern pattern = Pattern
            .compile("((\+[1-9]{3,4}|0[1-9]{4}|00[1-9]{3})\-?)?\d{8,20}");
    Matcher matcher = pattern.matcher(pPhoneNumber);

    if (matcher.matches()) return true;


    return false;
}

Format

格式

I made this according to my needs, and it accepts numbers:

我根据我的需要做了这个,它接受数字:

  1. CountryCode-Number
  2. Number
  1. 国家代码-号码
  2. 数字

Country Codes:

国家/地区代码:

They may have a: +, or either one or two zeros. Then, it may be followed by a -.

它们可能有一个: +,或者一个或两个零。然后,它后面可能跟一个-.

Accepts:

接受:

  • +456
  • 00456
  • +1234
  • 01234
  • +456
  • 00456
  • +1234
  • 01234

All above may or may not followed by a -

以上所有可能会或可能不会跟随一个 -

Rejects:

拒绝:

  • 0456
    • it should be:
      • 00456or+456or04444
  • 0456
    • 它应该是:
      • 00456+45604444

Number

数字

A simple number with 8-20 digits.

8-20 位的简单数字。

Accepts:

接受:

  • 00456-12345678
  • +457-12345678
  • +45712345678
  • 0045712345678
  • 99999999
  • 00456-12345678
  • +457-12345678
  • +45712345678
  • 0045712345678
  • 99999999

Extend it?

延长吗?

Feel free, so you may include support for .or '(' separators. Just make sure you escape them, e.g. for (use \(.

随意,所以你可以包含对.或 '(' 分隔符的支持。只要确保你对它们进行转义,例如(使用\(

回答by Matt Campbell

My own needs were very simple. I just needed to take a 7 or 10-digit number and put separators (a dash, period, some string of characters, etc.) between the area code, exchange, and exchange number. Any value passed into the method that is not all digits or is not a length of 7 or 10 is simply returned. A null value returns an empty string and a null value for the separator is treated like an empty string. My code:

我自己的需求很简单。我只需要取一个 7 或 10 位数字,并在区号、交换和交换号码之间放置分隔符(破折号、句点、一些字符串等)。任何传递给方法的不是全数字或长度不是 7 或 10 的值都将被简单地返回。空值返回空字符串,分隔符的空值被视为空字符串。我的代码:

import java.util.regex.Matcher;
import java.util.regex.Pattern;
// ...
private String formatPhoneNumber(String phnumber, String separator) {
  phnumber = (phnumber == null) ? "" : phnumber;
  if ((phnumber.length() != 7) && (phnumber.length() != 10)) { return phnumber; }

  // If we get here, 'phnumber' is for sure either 7 or 10 chars long

  separator = (separator == null) ? "" : separator;
  Pattern p = Pattern.compile("([0-9]*)");
  Matcher m = p.matcher(phnumber);
  if (m.matches()) {
   if (phnumber.length() == 7) {
     return phnumber.substring(0, 3) + separator + phnumber.substring(4);
    } else {
     return phnumber.substring(0, 3) + separator + phnumber.substring(3, 6)  
            + separator + phnumber.substring(6);
    }
  // If we get here, it means 1 or more of the chars in 'phnumber'
  // is not a digit and so 'phnumber' is returned just as passed in.
  return phnumber;
}