Регулярное выражение проверки номера телефона на все случаи жизни

Работая над одним большим международным проектом стала необходимость проверять введенный пользователем номер телефона на валидность, а так как, работаем мы еще и с юрлицами, то проверять надо еще и добавочный код.
Как известно, в мире несколько общепринятых форматов телефона, и работай мы только, например, с Францией, мы бы вообще могли бы на уровне поля ввода вбить шаблон типа ‘dd dd dd dd dd‘ и забыть о проверках. Но, например в Дании принят формат ‘(ddd) ddd-dddd‘, а пользователи из Великобритании привыкли почему-то писать dd.dd.dd.dd. Решено было призвать на помощь регулярные выражения.

Тут кстати очень пригодились Unit Tests и Data Provider, но в примере приведу просто обход массива с валидными номерами телефонов. Итак, составляем список из вариантов, которые будем считать валидными.

$phones = array(
'12 1234 123 1 ext1111',
'12 1234 123 1ext1111',
'12 12 12 12 12',
'12 1 1234 123456 x12345',
'+12 1234 1234',
'+12 12 12 1234',
'+12 1234 5678',
'+125 12345678',
'01.69.19.13.96',
'+33 (0) 12 12 1234',
'+375 29 144 78 24'
);

Далее, пишем регулярное выражение

$phoneRegexp = '/^((((\(\d{3}\))|(\d{3}-))\d{3}-\d{4})|(\+?\d{1,3}((-| |\.)(\(\d{1,4}\)(-| |\.|^)?)?\d{1,8}){1,5}))(( )?(x|ext)\d{1,5}){0,1}$/';

Потом можем написать простейший прототип тестирования

foreach($phones as $phone) {
   if(preg_match($phoneRegexp, $phone)) {
      print $phone . ' good <br />';
   } else {
      print '<font color="red">'.$phone . ' not good </font><br />';
   }
}

В итоге, получаем вот такую красоту:

12 1234 123 1 ext1111 good
12 1234 123 1ext1111 good
12 12 12 12 12 good
12 1 1234 123456 x12345 good
+12 1234 1234 good
+12 12 12 1234 good
+12 1234 5678 good
+125 12345678 good
01.69.19.13.96 good
+33 (0) 12 12 1234 good
+375 29 786 92 04 good

Отсутствие красных строк говорит о том, что мы сделали все правильно