Я пытаюсь извлечь определенную информацию с разных html-страниц. В основном информация представляет собой 10-значное число, которое может иметь разные формы:
000-000-0000 000 000 - 0000 0000000000
обратите внимание, что 000 000 - 0000000 не является действительным номером телефона, поэтому он не должен извлекать номер, если он содержит какие-либо дополнительные цифры
Я был бы признателен за любую помощь в создании идеального регулярного выражения, работающего во всех трех ситуациях. До сих пор я мог заставить его работать только для последнего (самого простого).
Это будет соответствовать всем трем приведенным вами примерам.
(\d{3}\s*-?\s*\d{3}\s*-?\s*\d{4})
Вот хорошая отправная точка:
<?php // all on one line... $regex = '/^(?:1(?:[. -])?)?(?:\((?=\d{3}\)))?([2-9]\d{2})(?:(?<=\(\d{3})\))? ?(?:(?<=\d{3})[.-])?([2-9]\d{2})[. -]?(\d{4})(?: (?i:ext)\.? ?(\d{1,5}))?$/'; // or broken up $regex = '/^(?:1(?:[. -])?)?(?:\((?=\d{3}\)))?([2-9]\d{2})' .'(?:(?<=\(\d{3})\))? ?(?:(?<=\d{3})[.-])?([2-9]\d{2})' .'[. -]?(\d{4})(?: (?i:ext)\.? ?(\d{1,5}))?$/'; ?>
Обратите внимание на не запечатленные подшаблоны (которые выглядят как (?:stuff)
). Это упрощает форматирование:
<?php $formatted = preg_replace($regex, '($1) $2-$3 ext. $4', $phoneNumber); // or, provided you use the $matches argument in preg_match $formatted = "($matches[1]) $matches[2]-$matches[3]"; if ($matches[4]) $formatted .= " $matches[4]"; ?>
И некоторые примеры для вас:
520-555-5542 :: MATCH 520.555.5542 :: MATCH 5205555542 :: MATCH 520 555 5542 :: MATCH 520) 555-5542 :: FAIL (520 555-5542 :: FAIL (520)555-5542 :: MATCH (520) 555-5542 :: MATCH (520) 555 5542 :: MATCH 520-555.5542 :: MATCH 520 555-0555 :: MATCH (520)5555542 :: MATCH 520.555-4523 :: MATCH 19991114444 :: FAIL 19995554444 :: MATCH 514 555 1231 :: MATCH 1 555 555 5555 :: MATCH 1.555.555.5555 :: MATCH 1-555-555-5555 :: MATCH 520-555-5542 ext.123 :: MATCH 520.555.5542 EXT 123 :: MATCH 5205555542 Ext. 7712 :: MATCH 520 555 5542 ext 5 :: MATCH 520) 555-5542 :: FAIL (520 555-5542 :: FAIL (520)555-5542 ext .4 :: FAIL (512) 555-1234 ext. 123 :: MATCH 1(555)555-5555 :: MATCH
Вероятно, вы получите много ложных срабатываний, если вы разрешите пробелы и тире, как вы предлагаете.
\b[0-9]{3}\s*[-]?\s*[0-9]{3}\s*[-]?\s*[0-9]{4}\b
редактировать
Добавлены границы слов.
Рассмотрим другие разделители, кроме дефиса, не говоря уже о круглых скобках.
(?:1\s*?[-.]?\s*)?(?:\(\s*d{3}\s*\)|d{3})\s*?[-.]?\s*\d{3}\s*?[-.]?\s*\d{4}\b
Ладно, может быть, это более всеобъемлющий, чем вам нужно, но на самом деле это может быть так сложно, как вам нравится. Вы можете расширить его, чтобы искать международные телефонные номера, расширения и т. Д., Но это может не стоить того.
<?php preg_match_all("/\+?[0-9][\d-\()-\s+]{5,12}[1-9]/", $string, $matches); print_r($matches); ?>