2016-04-28 29 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 

正如你所看到的,當我完全排除一個擴展(最後四個測試)時,它會中斷。如何糾正preg_match()正則表達式,使FAIL: ...行看起來像PASS: phone: 9417516550 ext: 0

+0

你絕對必須使用正則表達式? – GrumpyCrouton

+0

我想你可以減少正則表達式,請檢查我的答案。 –

回答

2

(.+$)手段在一行的結尾必須有1個或更多的符號。所以,如果你在電話號碼後什麼都沒有 - 那麼你的電話號碼會減少1個符號。

我建議使用(.*$)這意味着零個或多個符號。

+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

有趣,謝謝。儘管如此,這與我所嘗試的卻有很大不同。 –

0

從你的例子看起來它失敗時,沒有發現作爲分機。

一個解決辦法是強制轉換爲int $extension這樣的:

$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

這工作,upvoted和謝謝你。我接受了@u_mulder的回答,因爲他首先遇到了非貪婪的解決方案。 –

+0

好的,但要注意,我已經更改了一下你的正則表達式,允許在手機中使用空格字符和手機和擴展名之間的空格字符,並添加三元組,以在沒有失敗時獲得0 – 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