使用preg_match将字符串拆分为电话号码和扩展名

时间:2016-04-28 16:08:24

标签: php regex preg-replace preg-match phone-number

所以我试图拆分包含电话号码和分机号的字符串,因为有时字符串中存在扩展名。这是我的尝试:

$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

6 个答案:

答案 0 :(得分:2)

(.+$)表示在一行的末尾必须是1个或多个符号。因此,如果您在电话号码后面没有任何内容 - 那么您的电话号码将减少1个符号。

我建议使用(.*$),这意味着零个或多个符号。

答案 1 :(得分: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

答案 2 :(得分: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";
    }
}

对代码进行微小更改。

答案 3 :(得分:0)

从你的例子来看,当没有任何东西被发现时,它似乎失败了。

解决方案是像这样转换为int $extension

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

在此之后我们确信我们有一个integer,我们可以将if语句更改为:

|| $extension === 0)) {

答案 4 :(得分: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

答案 5 :(得分: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