разбиение строки на телефонный номер и добавочный номер с помощью 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?

1

Решение

(.+$) означает, что в конце строки должен быть 1 или более символов. Итак, если у вас ничего нет после номера телефона — тогда ваш номер телефона уменьшается на 1 символ.

Советую использовать (.*$) что означает ноль или более символов.

2

Другие решения

Я бы сделал все это в 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

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

С минимальными изменениями в вашем коде.

1

Из вашего примера это выглядит как сбой, когда ничего не найдено как ext.

Решение — привести к int $extension как это:

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

После этого мы уверены, что у нас есть integer и мы можем изменить оператор if на:

|| $extension === 0)) {
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
0
По вопросам рекламы [email protected]