2017-07-04 93 views
0

我試圖用Number::Phone from CPAN完成兩個任務:使用數::電話驗證和格式

  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::Phone::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' 

然而,由此產生錯誤的結果了。下面的代碼片段完美地工作,這正是我想要在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 

您的輸入是極大的讚賞。

+0

你認爲什麼是正確的?請提供您的預期產出和當前產出。這裏的Perl人可能不知道如何運行Java源代碼,它甚至不是[mcve],也不包含任何數字。 – simbabque

+0

謝謝@simbabque我編輯了我的帖子,以便更全面。 –

+0

由於它涉及Perl,所以Java人不能回答你的問題。如果問題不是*關於* java,那麼不要用「java」標記它 - 這是一個不相關的標記。 –

回答

0

當我運行了數第一個示例代碼,其中的兩個都無法解析:

17888888 - 這是顯而易見的,主叫號碼時::沒有一個國家代碼手機,這將不會被解析爲目前尚不清楚這是來自哪個國家

00923455555333 - 923根據快速谷歌搜索,巴基斯坦的國家代碼。在巴基斯坦撥打代碼的維基百科頁面沒有顯示455,導致我認爲這不是Number :: Phone或Wikipedia的已知區號。我懷疑這是一個無效號碼。

因此第一個數字:指定這個應該來自哪個國家。

如果您確定其他號碼是正確的,那麼您現在比Number :: Phone的開發者更瞭解這一點,並且我確信他很樂意以更完整的號碼的形式接收您的輸入::手機本地化軟件包。

事實上,你的Java代碼接受(可能)無效的數字並不一定意味着它是更正確的,只是它宣稱是一個正確的數字沒那麼挑剔。

編輯:

詢問電話::號碼來分析,而不是「00923455555333」輸入「923455555333」導致所需的輸出。

看着電話::號碼的來源:

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

它變得清晰,00被解釋爲「+00」,然後拒絕爲無效號碼。 View some discussion on that here

在我看來,你將不得不自己處理這個問題。 一種方法可能是簡單地用'+'替換前導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); 
    } 
} 
+0

感謝@bytepusher的迴應。兩個數字都是有效的。我期望使用「默認國家」,我還沒有想出如何在Number :: Phone中執行操作。參見(libphonenumber JavaScript Demo)'https:// rawgit.com/googlei18n/libphonenumber/master/javascript/i18n/phonenumbers/demo-compiled.html'。對於「默認國家」使用「BH」。我提供的所有數字都應該是有效的,我期望它們以E.164格式顯示在我的預期輸出中。 –

+1

我不確定這個「默認國家」來自哪裏 - 我沒有看到它在文檔中提到。 – bytepusher

+1

我提出了一個建議,在現在發現實際問題之後,您可能會如何處理這個問題。祝你好運! – bytepusher