Текущий REGEX
/^[\(]?(\d{0,3})[\)]?[\.]?[\/]?[\s]?[\-]?(\d{3})[\s]?[\.]?[\/]?[\-]?(\d{4})[\s]?[x]?(\d*)$/
имеет много проблем, в результате чего он соответствует всем следующим, среди прочего:
(0./ -000 ./-0000 x00000000000000000000000)
()./1234567890123456789012345678901234567890
\)\-555/1212 x
Я думаю, этот REGEX ближе к тому, что вы ищете:
/^(?:(?:(?:1[.\/\s-]?)(?!\())?(?:\((?=\d{3}\)))?((?(?!(37|96))[2-9][0-8][0-9](?<!(11)))?[2-9])(?:\((?<=\(\d{3}))?)?[.\/\s-]?([0-9]{2}(?<!(11)))[.\/\s-]?([0-9]{4}(?<!(555(01([0-9][0-9])|1212))))(?:[\s]*(?:(?:x|ext|extn|ex)[.:]*|extension[:]?)?[\s]*(\d+))?$/
или в разобранном виде:
<?
$pattern =
'/^ # Matches from beginning of string
(?: # Country / Area Code Wrapper [not captured]
(?: # Country Code Wrapper [not captured]
(?: # Country Code Inner Wrapper [not captured]
1 # 1 - CC for United States and Canada
[.\/\s-]? # Character Class ('.', '/', '-' or whitespace) for allowed (optional, single) delimiter between Country Code and Area Code
) # End of Country Code
(?!\() # Lookahead, only allowed if not followed by an open parenthesis
)? # Country Code Optional
(?: # Opening Parenthesis Wrapper [not captured]
\( # Opening parenthesis
(?=\d{3}\)) # Lookahead, only allowed if followed by 3 digits and closing parenthesis [lookahead never captured]
)? # Parentheses Optional
((?(?!(37|96))[2-9][0-8][0-9](?<!(11)))?[2-9]) # 3-digit NANPA-valid Area Code [captured]
(?: # Closing Parenthesis Wrapper [not captured]
\( # Closing parenthesis
(?<=\(\d{3}) # Lookbehind, only allowed if preceded by 3 digits and opening parenthesis [lookbehind never captured]
)? # Parentheses Optional
)? # Country / Area Code Optional
[.\/\s-]? # Character Class ('.', '/', '-' or whitespace) for allowed (optional, single) delimiter between Area Code and Central-office Code
([0-9]{2}(?<!(11))) # 3-digit NANPA-valid Central-office Code [captured]
[.\/\s-]? # Character Class ('.', '/', '-' or whitespace) for allowed (optional, single) delimiter between Central-office Code and Subscriber number
([0-9]{4}(?<!(555(01([0-9][0-9])|1212)))) # 4-digit NANPA-valid Subscriber Number [captured]
(?: # Extension Wrapper [not captured]
[\s]* # Character Class for allowed delimiters (optional, multiple) between phone number and extension
(?: # Wrapper for extension description text [not captured]
(?:x|ext|extn|ex)[.:]* # Abbreviated extensions with character class for terminator (optional, multiple) [not captured]
| # OR
extension[:]? # The entire word extension with character class for optional terminator
)? # Marker for Extension optional
[\s]* # Character Class for allowed delimiters (optional, multiple) between extension description text and actual extension
(\d+) # Extension [captured if present], required for extension wrapper to match
)? # Entire extension optional
$ # Matches to end of string
/x'; // /x modifier allows the expanded and commented regex
?>
Эта модификация предоставляет несколько улучшений.
- Создает настраиваемую группу элементов, которые могут соответствовать как расширение.Вы можете добавить дополнительные разделители для расширения. Это был исходный запрос. Расширение также допускает двоеточие после разделителя расширения.
- Преобразует последовательность из 4 необязательных разделителей (точка, пробел, косая черта или дефис) в символкласс, который соответствует только одному.
- Он группирует элементы соответствующим образом.В данном примере у вас могут быть открывающие круглые скобки без кода зоны между ними, и вы можете иметь метку расширения (пробел-x) без расширения.Это альтернативное регулярное выражение требует либо полного кода города, либо его отсутствия, либо полного внутреннего номера или его отсутствия.
- 4 компонента номера (код города, код центрального офиса, номер телефона и добавочный номер) имеют обратную ссылкуэлементы, которые вводятся в $ match в
preg_match()
. - . Использует lookahead / lookbehind, чтобы требовать совпадения скобок в коде области.
- Позволяет использовать 1- перед числом.(Предполагается, что все числа являются номерами США или Канады, что представляется разумным, поскольку в конечном итоге проводится сопоставление с ограничениями NANPA. Также запрещается сочетание префикса кода страны и кода зоны, заключенных в скобки.
- Он объединяется в NANPAправила устранения недопустимых телефонных номеров.
- Исключает коды городов в форме 0xx, 1xx 37x, 96x, x9x и x11, которые являются недействительными кодами NANPA.
- Устраняет коды центрального офисав форме 0xx и 1xx (недействительные коды центрального офиса NANPA).
- Исключает номера с формой 555-01xx (не присваивается из NANPA).
У него есть несколько незначительных ограничений. Они, вероятно, не важны, но отмечаются здесь.
- Нет ничего, что требовало бы повторного использования одного и того же разделителя, учитывая числа, например 800-555.1212, 800/555 1212, 800 555.1212 и т. Д.
- Нет ничего, что могло бы ограничить разделитель после области трескиe с круглыми скобками, с учетом чисел, таких как (800) -555-1212 или (800) /5551212.
Правила NANPA адаптированы из следующего REGEX, найденного здесь: http://blogchuck.com/2010/01/php-regex-for-validating-phone-numbers/
/^(?:1)?(?(?!(37|96))[2-9][0-8][0-9](?<!(11)))?[2-9][0-9]{2}(?<!(11))[0-9]{4}(?<!(555(01([0-9][0-9])|1212)))$/