Java电话号码格式API
我有一个数据库,里面有数百万个电话号码,所有格式都是免费的。也就是说,用户界面不强制任何约束,用户输入他们想要的任何内容 我要寻找的是一个JavaAPI,它可以尽最大努力将这些转换为一致的格式。理想情况下,API将获取自由文本值和国家代码,并生成有效的国际电话号码或引发异常 例如,系统中的电话号码可能类似于以下任何一种:Java电话号码格式API,java,Java,我有一个数据库,里面有数百万个电话号码,所有格式都是免费的。也就是说,用户界面不强制任何约束,用户输入他们想要的任何内容 我要寻找的是一个JavaAPI,它可以尽最大努力将这些转换为一致的格式。理想情况下,API将获取自由文本值和国家代码,并生成有效的国际电话号码或引发异常 例如,系统中的电话号码可能类似于以下任何一种: (555) 478-1123 555-478-1123 555.478.1123 5554781123 Iterable<PhoneNumberMatch>
(555) 478-1123
555-478-1123
555.478.1123
5554781123
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));
}
考虑到美国的国家,API将为所有这些产生“+1(555)478-1123”的值。确切的格式并不重要,只要是一致的
系统中也有没有区号的数字,如“478-1123”。在这种情况下,我希望出现一个异常或类似的情况
也可能有诸如“abc”之类的数据,它也会抛出异常
当然,我发布的示例有无数种变体,国际电话号码的复杂性也非常大,其验证规则相当复杂。这就是为什么我不考虑滚动自己。
有人见过这样的API吗?我不知道有这样的API,但它看起来可以通过使用正则表达式来实现。可能您无法将所有号码转换为有效格式,但大多数号码都是有效格式。有一些商业程序可以对国际电话号码进行格式化和验证,例如在某些国家甚至可以检查有效的区号。对于北美,提供了验证区号的功能。您可以编写自己的区号(对于美国电话格式):
- 从字符串中删除任何非数字字符
- 检查剩余字符串的长度是否为10个字符
- 在前三个字符周围加括号,在第六个和第七个字符之间加破折号
- 在字符串前加“+1”
更新:
谷歌最近发布了一个用于解析、格式化、存储和验证国际电话号码的软件。我认为没有办法确认没有区号,除非你的号码都来自一个国家(大概是美国),因为每个国家都有自己的区号规则
我会开始寻找详细的信息,如果有API来处理它(用Java或其他语言),它们可能也会链接到那里。我发现最好的是
javax.telephony
,可以在这里找到:
它有一个Address类,但遗憾的是该类并没有解决您的问题:(
好吧,也许你可以通过深入研究找到解决办法
除此之外,我的第一个想法是使用正则表达式。然而,对于这个特定的问题,这似乎是一种糟糕的解决方案。您可以尝试使用这个Java电话号码格式化库 它有数百个国家和格式的数据。的最新版本为许多新国家添加了元数据,并为先前列出的一些国家添加了更多详细信息 当前的源代码版本是r74,.jar文件是2.6版本。以前的.jar文件是为Java 1.6编译的,但从libphonenumber版本2.5.1开始,它们现在是为Java 1.5及以上版本编译的 别忘了还有一个代码到JavaScript的直接端口
欢迎错误报告。积极鼓励更新元数据,因为即使是许多国家的官方政府发布的区号列表也不完整或过时。对于类似“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"
一旦可以做到这一点,使用谷歌的电话号码API,我们可以轻松解析这些序列,并将其重新格式化为其他形式,如“+33 1 44 55 66 77”,如下所示:
(555) 478-1123
555-478-1123
555.478.1123
5554781123
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));
}
Iterable numbers=PhoneNumberUtil.getInstance().findNumbers(textWithPhoneNums,“FR”);
for(Iterator Iterator=numbers.Iterator();Iterator.hasNext();){
PhoneNumberMatch pnm=迭代器.next();
PhoneNumber=pnm.number();
System.out.println(PhoneNumberUtil.getInstance().formatOutOfCountryCallingNumber(number,null));
}
Simple regex解析器
格式
我根据我的需要做了这个,它接受数字:
+
,或者一个或两个零。
然后,它后面可能跟一个-
接受:
+456
00456
+1234
01234
-
拒绝:
0456
- 应该是:
或00456
或+456
04444
- 应该是:
00456-12345678
+457-12345678
+45712345678
0045712345678
9999999
请随意,因此您可以包括对
或“(”分隔符的支持。只需确保将它们转义,例如对(
使用\(
我自己的需要非常简单。我只需要取一个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;
}
不要重新发明轮子;使用API,例如。 这个API也提供了很好的格式。 示例:
String number = "(555) 478-1123";
PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
try {
Phonenumber.PhoneNumber phoneNumber = phoneNumberUtil.parse(number, Locale.US.getCountry());
} catch (NumberParseException e) {
// error handling
}
您甚至可以使用phoneNumber对象在将其保存到DB或其他任何地方之前将其格式化为有效的电话号码。我已经创建了一个He
var globalnumber = PhoneNumberHelper.correctNumber(contact.mobile, context)
val code = StorageAdapter.get(context).userCountryCode
implementation 'com.googlecode.libphonenumber:libphonenumber:8.8.0'