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

时间:2017-07-04 15:21:36

标签: perl unix perl-module libphonenumber

我正在尝试使用Number::Phone from CPAN来完成2项任务:

  1. 验证电话号码;和
  2. 以E.164表示法格式化数字。
  3. 但是,我无法弄清楚它是如何工作的。我的示例代码是:

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

    预期产出:

    #!/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";
    }
    

    但结果不正确。我尝试使用Number::Phone::Normalize,但仍未成功:

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

    具有相同的预期输出:

    // 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>");
            }
        }
    }
    

    然而,这也产生了错误的结果。下面的代码片段Java代码完美无缺,这正是我想要在Perl中实现的。

    % 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
    
    @model MainBit.Captcha.ViewModel.CaptchaViewModel
    <fieldset>
        <label class="required">
            @T("Type captcha")<br />
            <img src="@(Model.Src)"/>
        </label>
        <input id="@(Model.ValueFieldName)" name="@(Model.ValueFieldName)" required="required" type="text" value="">
        <input id="@(Model.GuidFieldName)" name="@(Model.GuidFieldName)" type="hidden" value="@(Model.Guid)">
        @*@Html.TextBox(Model.ValueFieldName, "", new { required = "required" })
        @Html.Hidden(Model.GuidFieldName, Model.Guid)*@
    </fieldset>
    
    
    <input id="@(Model.ValueFieldName)" name="@(Model.ValueFieldName)" required="required" type="text" value="">
    <input id="@(Model.GuidFieldName)" name="@(Model.GuidFieldName)" type="hidden" value="@(Model.Guid)">
    

    非常感谢您的意见。

1 个答案:

答案 0 :(得分:0)

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

17888888 - 很明显,在没有国家代码的情况下拨打Number :: Phone时,这将不会被解析,因为它不清楚这是来自哪个国家

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

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

如果您确定其他数字是正确的,那么您目前比Number :: Phone的开发者更了解这一点,我确信他很乐意接受您的输入。更完整的Number :: Phone本地化包。

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

编辑:

要求电话::号码来解析输入&#39; + 923455555333&#39;而不是&#39; 00553455555333&#39;导致期望的输出。

查看Phone :: Number:

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

很明显00被解释为&#39; + 00&#39;然后被拒绝为无效号码。 View some discussion on that here

在我看来,你必须自己处理这件事。 一种方法可能是简单地用&#39; +&#39;替换前导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);
    }
}