使用 Number::P hone 进行验证和格式化



我正在尝试使用 CPAN 中的 Number::P hone 来完成 2 个任务:

  1. 验证电话号码;以及
  2. 以 E.164 表示法设置数字格式。

但是,我无法弄清楚它是如何工作的。我的示例代码是:

#!/usr/bin/perl -w
use strict;
use warnings;
use Number::Phone;
foreach my $fnum ( '17888888', '97338888888', '00923455555333', '+97366767777' , '38383838') {
my $phone = Number::Phone->new($fnum);
my $norm = "";
eval {
$norm = $phone->format_using('E123'); # or 'Raw'
print "E164 => '$norm'n";
} or do {
print STDERR "Unable to parse '$fnum'n";
}
}

预期产出:

E164 => '+97317888888'
E164 => '+97338888888'
E164 => '+923455555333'
E164 => '+97366767777'
E164 => '+97338383838'

但结果是不正确的。我尝试使用Number::P hone::Normalize,但仍然没有成功:

#!/usr/bin/perl -w
use strict;
use warnings;
use Number::Phone::Normalize;
my %params = ( 
'CountryCode'=>'973',
'IntlPrefix' =>'00',
'CountryCodeOut'=>'973',
'IntlPrefixOut' => '+',
);
my $nlz = Number::Phone::Normalize->new( %params );
foreach my $number ('17888888', '97338888888', '00923455555333', '+97366767777' , '38383838') {
my $e164 = $nlz->intl( $number );
print "E164 => '$e164'n";
}

具有相同的预期输出:

E164 => '+97317888888'
E164 => '+97338888888'
E164 => '+923455555333'
E164 => '+97366767777'
E164 => '+97338383838'

然而,这也产生了错误的结果。下面的Java代码片段运行良好,这就是我试图在Perl中实现的目标。

// Uses libphonenumber: http://code.google.com/p/libphonenumber/
// setenv CLASSPATH .:libphonenumber-8.5.2.jar
// libphonenumber
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
public class ValidateList {
public static void main(String[] args) {
try {
if (args.length != 1) {
throw new IllegalArgumentException("Invalid number of arguments.");
}
String file = args[0];
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try (java.io.BufferedReader br = new java.io.BufferedReader(new java.io.FileReader(file))) {
String line = null;
while ((line = br.readLine()) != null) {
try {
PhoneNumber phoneNumber = phoneUtil.parse(line, "BH");
boolean isValid = phoneUtil.isValidNumber(phoneNumber);
if (isValid) {
System.out.println( "E164 => " + phoneUtil.format(phoneNumber, PhoneNumberFormat.E164) );
}
else {
System.err.println( "Invalid => " + line);
}
} 
catch (NumberParseException e) {
System.err.println("NumberParseException for ("+line+"): " + e.toString());
}
}
}
}
catch (Exception e) {
System.err.println(e);
System.err.println("Usage: java ValidateList <fileNameWithPhoneNumbers>");
}
}
}
% cat input.txt
17888888
97338888888
00923455555333
+97366767777
38383838
% javac -cp libphonenumber-8.5.2.jar ValidateList.java
% java -cp .:libphonenumber-8.5.2.jar ValidateList input.txt 
E164 => +97317888888
E164 => +97338888888
E164 => +923455555333
E164 => +97366767777
E164 => +97338383838

非常感谢您的意见。

当我运行数字的第一个示例代码时,其中两个无法解析:

17888888 - 这是显而易见的,在没有国家/地区代码的情况下调用 Number::P hone 时,这不会被解析,因为不清楚这是来自哪个国家/地区

根据快速的谷歌搜索,00923455555333 - 923是巴基斯坦的国家代码。维基百科在巴基斯坦拨号代码的页面显示没有455,导致我认为这不是Number::P hone或维基百科的已知区号。我怀疑这是一个无效的数字。

因此,对于第一个数字:指定这应该来自哪个国家。

如果您确定另一个数字是正确的,那么您目前比 Number::P hone 的开发人员更了解这一点,我相信他很乐意以更完整的 Number::P hone 本地化包的形式收到您的输入。

您的 Java 代码接受(可能(无效数字的事实并不一定意味着它更正确,只是它在声明为正确数字时不那么挑剔。

编辑:

询问电话::号码以解析输入"+923455555333"而不是"00923455555333"会导致所需的输出。

查看电话::号码的来源:

# ... processing input arguments
$number = "+$number" unless($number =~ /^+/);

很明显,00被解释为"+00",然后被拒绝为无效数字。 在此处查看有关此内容的一些讨论

在我看来,你必须自己处理这个问题。 一种方法可能是简单地将前导 00 替换为"+"——最好仅在解析失败时才使用。

如果您明确另一个数字应该属于哪个国家/地区,则可以解析它。

也许是这样的:

my $phone = Number::Phone->new($fnum);
unless ($phone){
$phone = Number::Phone->new('BH',$fnum);
if ( !$phone && $fnum =~ s/^00/+/ ){
# You should probably check the discussion I linked.
# There may well be problems with this approach!
$phone = Number::Phone->new($fnum);
}
}

最新更新