2016-04-28 11 views
1

電話番号と内線番号を含む文字列を分割しようとしています。これは私の試みです:preg_matchを使用して電話番号と内線番号に文字列を分割する

$tests[] = "941-751-6550 ext 2204"; 
$tests[] = "(941) 751-6550 ext 2204"; 
$tests[] = "(941)751-6550 ext 2204"; 
$tests[] = "9417516550 ext 2204"; 
$tests[] = "941-751-6550 e 2204"; 
$tests[] = "941-751-6550 ext 2204 "; 
$tests[] = "941-751-6550 extension 2204"; 
$tests[] = "941-751-6550 x2204"; 
$tests[] = "(941) 751-6550"; 
$tests[] = "(941)7516550"; 
$tests[] = "941-751-6550 "; 
$tests[] = "941-751-6550"; 

foreach ($tests as $test) { 
    preg_match('#([\(\)\s0-9\-]+)(.+$)#',$test,$matches); 
    $phone = preg_replace('#[\-\(\)\s]#','',$matches[1]); 
    $extension = preg_replace('#[^0-9]#','',$matches[2]); 
    if ($phone == '9417516550' 
     && ($extension == '2204' 
      || $extension == '0')) { 
       echo "PASS: phone: $phone ext: $extension<br />"; 
    } else { 
     echo "FAIL: phone: $phone ext: $extension<br />"; 
    } 
} 

しかし、私はそれが適切に電話番号と内線を分割かどうかを確認するためにこれらのテストを実行したときに、私は次の出力を得る:

PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
FAIL: phone: 941751655 ext: 0 
FAIL: phone: 941751655 ext: 0 
FAIL: phone: 9417516550 ext: 
FAIL: phone: 941751655 ext: 0 

あなたが見ることができるように、私がエクステンションを完全に除外すると(最後の4回のテスト)それは壊れます。 FAIL: ...の行がPASS: phone: 9417516550 ext: 0のようになるように、preg_match()正規表現を修正するにはどうすればよいですか?

+0

あなたは絶対に正規表現を使用する必要がありますか? – GrumpyCrouton

+0

私はあなたが正規表現を減らすことができると思う、私の答えを確認してください。 –

答えて

2

(.+$)手段行末には1つ以上のシンボルが必要です。あなたが電話番号の後に何も持っていなければ、あなたの電話番号は1記号だけ減らされます。

(.*$)は0個以上の記号を意味することをお勧めします。

+0

これはそれです!解決策である貪欲でないマッチングを最初に指摘したので、私はあなたの答えを受け入れました。残りは実装の詳細です。 –

1

私はpreg_matchのすべてをやっています。数字が非国際的だとすれば、これはうまくいくと思います。

foreach ($tests as $test) { 
    preg_match('#\(?(\d{3})\)?[-\h]?(\d{3})[-\h]?(\d{4})\h*(?:e?x?t?(?:ension)?\h(\d+))?#',$test,$matches); 
    $phone = $matches[1] . $matches[2] . $matches[3]; 
    $extension = !empty($matches[4]) ? $matches[4] : 0; 
    if ($phone == '9417516550' 
     && ($extension == '2204' || $extension == '0')) { 
      echo "PASS: phone: $phone ext: $extension<br />"; 
    } else { 
     echo "FAIL: phone: $phone ext: $extension<br />"; 
    } 
} 

デモ:https://eval.in/561720
Regex101デモ:https://regex101.com/r/mG9iD1/1

+0

面白い、ありがとう。それは私が試していたものとはまったく異なりますが、それにもかかわらずupvotedです。 –

0

あなたの例から何を内線として見つからなかったときに、それが失敗したように見えます。

ソリューションは、このような$extensionをintにキャストすることです。この後

$extension = intval($extension); //If nothing found will be 0 

我々はintegerを持っていると我々はにif文を変更することができることを確信している:

|| $extension === 0)) { 
1

期待どおりに動作し、テスト済みです。

foreach ($tests as $test) { 
    preg_match('#([\(\)0-9\-]+\s*[\(\)0-9\-]+)\s*(.*$)#',$test,$matches); 
    $phone = preg_replace('#[\-\(\)\s]#','',$matches[1]); 
    $extension = ($matches[2] == "") ? '0' : preg_replace('#[^0-9]#','',$matches[2]); 
    if ($phone == '9417516550' 
     && ($extension == '2204' 
      || $extension == '0')) { 
       echo "PASS: phone: $phone ext: $extension<br />\n"; 
    } else { 
     echo "FAIL: phone: $phone ext: $extension<br />\n"; 
    } 
} 

コードを最小限に変更してください。

+0

これはうまくいきました。私は@u_mulderの答えを彼が非貪欲な解決策を最初に見つけたので受け入れました。 –

+0

しかし、注意してください、私はあなたのregexpを電話機のスペース文字と電話機と拡張子の間のスペース文字を許可するように少し変更しました。そして、エクステンションがないときに0を得るために3値文字を追加します – lamp76

0
$pns = <<< LOL 
941-751-6550 ext 2204 
(941) 751-6550 ext 2204 
(941)751-6550 ext 2204 
9417516550 ext 2204 
941-751-6550 e 2204 
941-751-6550 ext 2204 
941-751-6550 extension 2204 
941-751-6550 x2204 
(941) 751-6550 
(941)7516550 
941-751-6550 
941-751-6550 
LOL; 

preg_match_all('/^([(\d)\-]+)\s?(?:e.*?|x.*?)?(\d+)?$/sim', $pns, $matches, PREG_PATTERN_ORDER); 
for ($i = 0; $i < count($matches[1]); $i++) { 
    $phone = preg_replace('#[\-\(\)\s]#','', $matches[1][$i]); 
    $extension = preg_replace('#[^0-9]#','', $matches[2][$i]); 
    if ($phone == '9417516550' && $extension == '2204') { 
      echo "PASS: phone: $phone ext: $extension\n"; 
    } else { 
      echo "FAIL: phone: $phone ext: 0\n"; 
    } 
} 

出力:

PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
FAIL: phone: 9417516550 ext: 0 
FAIL: phone: 9417516550 ext: 0 
FAIL: phone: 9417516550 ext: 0 
FAIL: phone: 9417516550 ext: 0 

Ideone Demo

0

正直なところ、あなたが最初の後に何かをオフに分割し、その後、数字以外の文字をストリッピングする方がいいでしょう10を拡張子とする。概念的には同等ですが、本質的に遅い複数の正規表現を実行するよりも、より簡単で絶対的ではなく、より効率的です。

foreach($tests as $test){ 
    $phone = preg_replace("/[^0-9]/", "", $test); 
    $extension = substr($phone,10); 
    $phone = substr($phone,0,10); 
    if(empty($extension)){ 
     $extension = '0'; 
    } 
    if ($phone == '9417516550' 
     && ($extension == '2204' 
      || $extension == '0')) { 
       echo "PASS: phone: $phone ext: $extension<br />\n"; 
    } else { 
     echo "FAIL: phone: $phone ext: $extension<br />\n"; 
    } 
} 

出力:

PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 2204 
PASS: phone: 9417516550 ext: 0 
PASS: phone: 9417516550 ext: 0 
PASS: phone: 9417516550 ext: 0 
PASS: phone: 9417516550 ext: 0