Какое регулярное выражение будет соответствовать действительным международным телефонным номерам?

113

Мне нужно определить, действителен ли номер телефона, прежде чем пытаться его набрать. Телефонный звонок может быть осуществлен в любую точку мира.

Какое регулярное выражение будет соответствовать действительным международным телефонным номерам?

Абтин Форузанде
источник
Как какое-либо регулярное выражение обрабатывает ошибки, такие как не обслуживаемые номера? Просто попробуйте позвонить и обработать неверный номер, как и другие ошибки.
3
Хотя вы правы в том, что регулярное выражение не может это определить, каждая попытка исходящего трафика требует времени и ресурсов. Выполнение быстрой проверки правильности номера гарантирует, что явно поддельный вызов не заблокирует ценный канал.
Abtin Forouzandeh
1
LOL @ paxdiablo .... Я думаю, 1-800-CALL-HELP пройдет ваш тест RegExp ... lol
Buhake Sindi
1
В этом вопросе неясно, должны ли номера быть действительными при вызове из США или из любой страны мира, потому что большинство приведенных ниже решений не проверяют некоторые действительные номера (например, 0030 210 12312312 - действительный Греческий номер для
звонков
1
@JonHanna Я согласен с точкой зрения, но, с другой стороны, с точки зрения UX, разве вы не думаете, что если пользователь вводит число 00XX ... X, тест должен пройти? Бывают случаи, когда пользователи (например, пожилые люди) даже не знают, что такое + и как набрать его на цифровой клавиатуре / клавиатуре телефона. Кроме того, я все еще могу утверждать, что 00XXX - действительный международный номер (т.е. в контексте пользователя), где вместо + использовался код выхода.
Xeroxoid

Ответы:

96
\+(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|
2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|
4[987654310]|3[9643210]|2[70]|7|1)\d{1,14}$

Правильный формат для сопоставления общего международного телефонного номера. Я заменил международный код доступа 011, ориентированный на наземные линии связи в США, на стандартный идентификатор международного кода доступа «+», сделав его обязательным. Я также изменил минимум для национального номера как минимум на одну цифру.

Обратите внимание, что если вы вводите номера в этом формате в адресную книгу своего мобильного телефона, вы можете успешно звонить по любому номеру из адресной книги, независимо от того, куда вы путешествуете. Для наземных линий замените плюс международным кодом доступа страны, из которой вы звоните.

Обратите внимание, что при этом НЕ принимаются во внимание правила национального плана нумерации - в частности, он допускает нули и единицы в местах, которые могут быть запрещены национальными планами нумерации, а также допускает длину номеров больше, чем национальный план нумерации для некоторых стран (например, США).

Эрик
источник
5
Мне кажется разумным. Я собираюсь использовать это
Роберт Джонстон
17
Это неверно. Европейские телефонные номера могут начинаться с двойного 0 без + в начале. Таким образом, такой номер телефона, как: +44 8984 1234 (Великобритания), также вполне действителен, если записан 0044 8984 1234, который это регулярное выражение (и другие ответы) не поддерживает.
Xeroxoid
4
В сочетании с улучшениями @fezfox (?) И оптимизацией по длине:^\+((?:9[679]|8[035789]|6[789]|5[90]|42|3[578]|2[1-689])|9[0-58]|8[1246]|6[0-6]|5[1-8]|4[013-9]|3[0-469]|2[70]|7|1)(?:\W*\d){0,13}\d$
SamWhan 05
1
+1. С точки зрения UX, да, возможно, имеет смысл разрешить 00вперед. С точки зрения разработки и обслуживания, я бы сказал, что совершенно нормально заставлять все числа начинать с +или даже заменять 00на +каждый раз, когда вы его получаете - особенно с учетом того, что большинство людей знают о +формате (который в большинстве международных полей ввода телефона все равно требуется). К тому же это однострочное исправление, и оно более читабельно. Такой подход также гарантирует, что все номера телефонов имеют один и тот же формат, и сделает вашу проверку менее подверженной ошибкам, что сделает все это более удобным в обслуживании.
milosmns
1
Кроме того, в "старые" времена SMS до EDGE (обычный GSM) использование 00не могло отправить сообщение правильно, тогда как начало с a +всегда работало на международном уровне. Мы можем сойти с ума и сделать это сверхсложным, но иногда можно / стоит отказаться от некоторых ограничений, чтобы облегчить нашу жизнь :)
milosmns
66

Все коды стран определены ITU. Следующее регулярное выражение основано на ITU-T E.164 и Приложении к Оперативному бюллетеню ITU № 930 - 15.IV.2009 . Он содержит все текущие коды стран и коды, зарезервированные для использования в будущем. Хотя его можно немного сократить, я решил включить каждый код отдельно.

Это для звонков из США. Для других стран замените код доступа к международной связи (011 в начале регулярного выражения) на любой, подходящий для тарифного плана этой страны .

Также обратите внимание, что ITU E.164 определяет максимальную длину полного международного телефонного номера до 15 цифр. Это означает, что трехзначный код страны дает до 12 дополнительных цифр, а однозначный код страны может содержать до 14 дополнительных цифр. Следовательно

[0-9]{0,14}$

конец регулярного выражения.

Что наиболее важно, это регулярное выражение не означает, что номер действителен - каждая страна определяет свой собственный внутренний план нумерации. Это только гарантирует, что код страны действителен.

283 | 282 | 281 | 280 | 269 | 268 | 267 | 266 | 265 | 264 | 263 | 262 | 261 | 260 | 259 | 258 | 257 | 256 | 255 | 254 | 253 | 252 | 251 | 250 | 249 | 248 | 247 | 246 | 245 | 244 | 243 | 242 | 241 | 240 | 239 | 238 | 237 | 236 | 235 | 234 | 233 | 232 | 231 | 230 | 229 | 228 | 227 | 226 | 225 | 224 | 223 | 222 | 221 | 220 | 219 | 218 | 217 | 216 | 215 | 214 | 213 | 212 | 211 | 210 | 98 | 95 | 94 | 93 | 92 | 91 | 90 | 86 | 84 | 82 | 81 | 66 | 65 | 64 | 63 | 62 | 61 | 60 | 58 | 57 | 56 | 55 | 54 | 53 | 52 | 51 | 49 | 48 | 47 | 46 | 45 | 44 | 43 | 41 | 40 | 39 | 36 | 34 | 33 | 32 | 31 | 30 | 27 | 20 | 7 | 1) [0-9] {0, 14} $

Абтин Форузанде
источник
12
Почти правильно ... "011" не является частью международного кода. Это просто то, что нужно набрать людям в США, чтобы сделать международный звонок. Этот префикс будет меняться в зависимости от того, откуда вы набираете номер ... Так что этот префикс НЕ является частью номера.
Габриэль Магана
3
@gmagana - я упоминаю об этом в своем ответе (параграф 2)
Абтин Форузандех
1
Я хочу сказать, что это не часть телефонного номера. Это все равно, что сказать, что префикс для междугородного набора в США «1» является частью телефонного номера.
Габриэль Магана
1
@gmagana - хотя вы правы, что это не часть номера телефона, технически это необходимо для совершения звонка.
Abtin Forouzandeh
2
@ Роджер Пейт: Я потратил немного времени на то, чтобы понять это, и надеюсь, что это будет полезно другим. Я также надеялся, что у кого-то может быть лучшее решение (поэтому я не пометил свой ответ как принятый).
Abtin Forouzandeh
32

Это дальнейшая оптимизация.

\+(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|
2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|
4[987654310]|3[9643210]|2[70]|7|1)
\W*\d\W*\d\W*\d\W*\d\W*\d\W*\d\W*\d\W*\d\W*(\d{1,2})$

(i) позволяет использовать действительные международные префиксы
(ii), за которыми следуют 9 или 10 цифр, с любым типом или размещением разделителей (кроме двух последних цифр)

Это будет соответствовать:
+ 1-234-567-8901
+ 61-234-567-89-01
+ 46-234 5678901
+1 (234) 56 89 901
+1 (234) 56-89 901
+46.234.567.8901
+1 / 234/567/8901

Fezfox
источник
Я знаю, что это старый ответ, но есть ли возможность сделать 1 необязательным для американских номеров?
Адам Фратино
Что вы хотите сделать, так это (i) сделать «+» необязательным и (ii) международный код необязательным. Так поместите "?" после + и после первой закрывающей скобки.
fezfox
@ManosPasgiannis ну да, как указано «с последующими 9 или 10 цифрами». Это могло бы появиться на кипре, который вы используете 8, поэтому просто измените последнюю последовательность, удалив один раз экземпляр \ d \ W * и сделав последнее выражение (\ d {1,3})
fezfox
22

Вы можете использовать библиотеку libphonenumber от Google.

PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
String decodedNumber = null;
PhoneNumber number;
    try {
        number = phoneNumberUtil.parse(encodedHeader, null);
        decodedNumber = phoneNumberUtil.format(number, PhoneNumberFormat.E164);
    } catch (NumberParseException e) {
        e.printStackTrace();
    }
Пауло Фидальго
источник
2
Это могло бы быть хорошим решением, но просто чтобы проверить номера телефонов, перед использованием этой библиотеки вам нужно импортировать огромное количество js ... потому что libphonenumber.js нуждается в библиотеке закрытия ... это не простое решение: /
J. BizMai
11

Это будет работать для международных номеров;

C #:

@"^((\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,5})|(\(?\d{2,6}\)?))(-| )?(\d{3,4})(-| )?(\d{4})(( x| ext)\d{1,5}){0,1}$"

JS:

/^((\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,5})|(\(?\d{2,6}\)?))(-| )?(\d{3,4})(-| )?(\d{4})(( x| ext)\d{1,5}){0,1}$/
MADol
источник
11

Я использую такой:

/([0-9\s\-]{7,})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$/

Преимущества: распознает начало + или 011, позволяет ему быть сколь угодно длинным и поддерживает множество соглашений о расширениях. (#, x, ext, расширение)

TOBlender
источник
Этот формат очень близок к большинству международных форматов телефонных номеров.
Feela
9

Вот «оптимизированная» версия вашего регулярного выражения:

^011(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|
2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|
4[987654310]|3[9643210]|2[70]|7|1)\d{0,14}$

Вы можете заменить \ds на, [0-9]если ваш синтаксис регулярного выражения не поддерживает \d.

Лоуренс Гонсалвес
источник
7

Для iOS SWIFT я нашел это полезным,

let phoneRegEx = "^((\\+)|(00)|(\\*)|())[0-9]{3,14}((\\#)|())$"
Мохаммад Заид Патан
источник
не удалось набрать +91 9999999999
Сахил Махаджан
6

Изменено регулярное выражение @Eric - добавлен список всех кодов стран ( взяты из xxxdepy @ Github . Надеюсь, вы найдете это полезным:

/(\+|00)(297|93|244|1264|358|355|376|971|54|374|1684|1268|61|43|994|257|32|229|226|880|359|973|1242|387|590|375|501|1441|591|55|1246|673|975|267|236|1|61|41|56|86|225|237|243|242|682|57|269|238|506|53|5999|61|1345|357|420|49|253|1767|45|1809|1829|1849|213|593|20|291|212|34|372|251|358|679|500|33|298|691|241|44|995|44|233|350|224|590|220|245|240|30|1473|299|502|594|1671|592|852|504|385|509|36|62|44|91|246|353|98|964|354|972|39|1876|44|962|81|76|77|254|996|855|686|1869|82|383|965|856|961|231|218|1758|423|94|266|370|352|371|853|590|212|377|373|261|960|52|692|389|223|356|95|382|976|1670|258|222|1664|596|230|265|60|262|264|687|227|672|234|505|683|31|47|977|674|64|968|92|507|64|51|63|680|675|48|1787|1939|850|351|595|970|689|974|262|40|7|250|966|249|221|65|500|4779|677|232|503|378|252|508|381|211|239|597|421|386|46|268|1721|248|963|1649|235|228|66|992|690|993|670|676|1868|216|90|688|886|255|256|380|598|1|998|3906698|379|1784|58|1284|1340|84|678|681|685|967|27|260|263)(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)\d{4,20}$/
Dev
источник
Работает как шарм. Также для голландских телефонных номеров. Спасибо!
mauvm
2

Очевидно, существует множество способов сделать это, о чем свидетельствуют все различные ответы, данные до сих пор, но я добавлю сюда свои 0,02 доллара и предоставлю регулярное выражение ниже, которое немного короче, чем почти все вышеперечисленное , но и более тщательно, чем большинство других. У этого также есть приятный побочный эффект, заключающийся в том, что код страны остается в $ 1, а местный номер - в $ 2.

^ \ + (? = \ d {5,15} $) (1 | 2 [078] | 3 [0-469] | 4 [013-9] | 5 [1-8] | 6 [0-6] | 7 | 8 [1-469] | 9 [0-58] | [2-9] ..) (\ d +) $

трекиназ
источник
2

Никакой критики по поводу этих замечательных ответов, я просто хочу представить простое решение, которое я использую для наших создателей административного контента:

^(\+|00)[1-9][0-9 \-\(\)\.]{7,}$

Принудительно начинать с плюса или двух нулей и использовать хотя бы немного чисел, пробелы, фигурные скобки, минус и точка не являются обязательными, и никакие другие символы. Вы можете безопасно удалить все не-числа и использовать это в tel: input. Числа будут иметь общую форму представления, и мне не нужно беспокоиться о том, что они будут слишком ограничительными.

Blackbam
источник
1

Простая версия для европейских номеров, которая соответствует номерам типа 0034617393211, а также длинным, как 004401484172842.

^0{2}[0-9]{11,}

Надеюсь, поможет :·)

Рок Боронат
источник
1
public static boolean validateInternationalPhoneNumberFormat(String phone) {
    StringBuilder sb = new StringBuilder(200);

    // Country code
    sb.append("^(\\+{1}[\\d]{1,3})?");

    // Area code, with or without parentheses
    sb.append("([\\s])?(([\\(]{1}[\\d]{2,3}[\\)]{1}[\\s]?)|([\\d]{2,3}[\\s]?))?");

    // Phone number separator can be "-", "." or " "

    // Minimum of 5 digits (for fixed line phones in Solomon Islands)
    sb.append("\\d[\\-\\.\\s]?\\d[\\-\\.\\s]?\\d[\\-\\.\\s]?\\d[\\-\\.\\s]?\\d[\\-\\.\\s]?");

    // 4 more optional digits
    sb.append("\\d?[\\-\\.\\s]?\\d?[\\-\\.\\s]?\\d?[\\-\\.\\s]?\\d?$");

    return Pattern.compile(sb.toString()).matcher(phone).find();
}
Cássio
источник
1
Хотя этот фрагмент кода может ответить на вопрос, он не предоставляет никакого контекста, чтобы объяснить, как и почему. Вы можете добавить одно или два предложения, чтобы объяснить свой ответ.
brandonscript
1

Вот регулярное выражение для следующих наиболее распространенных сценариев телефонных номеров. Хотя это адаптировано с точки зрения США для кодов регионов, оно работает для международных сценариев.

  1. Фактический номер должен состоять только из 10 цифр.
  2. Для номеров США код города может быть заключен в круглые скобки ().
  3. Код страны может состоять из 1–3 цифр. По желанию может предшествовать знак +.
  4. Между кодом страны, кодом города и остальной частью номера могут быть дефисы, пробелы, точки или отсутствие пробелов.
  5. Действительный номер телефона не может состоять только из нулей.

    ^(?!\b(0)\1+\b)(\+?\d{1,3}[. -]?)?\(?\d{3}\)?([. -]?)\d{3}\3\d{4}$

Объяснение:

    ^ - start of expression  
    (?!\b(0)\1+\b) - (?!)Negative Look ahead. \b - word boundary around a '0' character. \1 backtrack to previous capturing group (zero). Basically don't match all zeros.  
    (\+?\d{1,3}[. -]?)? - '\+?' plus sign before country code is optional.\d{1,3} - country code can be 1 to 3 digits long. '[. -]?' - spaces,dots and dashes are optional. The last question mark is to make country code optional.  
    \(?\d{3}\)? - '\)?' is to make parentheses optional. \d{3} - match 3 digit area code.  
    ([. -]?) - optional space, dash or dot
    $ - end of expression

Дополнительные примеры и объяснения - https://regex101.com/r/hTH8Ct/2/

Appy
источник
1

Я использовал это ниже:

^(\+|00)[0-9]{1,3}[0-9]{4,14}(?:x.+)?$

Формат + CCC.NNNNNNNNNNxEEEE или 00CCC.NNNNNNNNNNxEEEE

Телефонный номер должен начинаться с "+" или "00" для международного звонка. где C - это код страны из 1–3 цифр,

N до 14 цифр,

и E - (необязательное) расширение.

Ведущий знак плюс и точка после кода страны обязательны. Литеральный символ «x» требуется только в том случае, если предусмотрено расширение.

Русонур Джаман
источник
0

Международный план нумерации основан на ITU E.164. плане нумерации . Думаю, это отправная точка вашего регулярного выражения.

Я обновлю это, если мне удастся создать регулярное выражение на основе нумерации ITU E.164.

Бухаке Синди
источник
0

Это регулярное выражение работает с телефонными номерами Индии, Канады, Европы, Новой Зеландии, Австралии и США, а также с их кодами стран:

"^(\+(([0-9]){1,2})[-.])?((((([0-9]){2,3})[-.]){1,2}([0-9]{4,10}))|([0-9]{10}))$"

Харша Гарг
источник
0

Это работает для меня, без префикса 00, 001, 0011 и т. Д .:

/^\+*(\d{3})*[0-9,\-]{8,}/
Redwud
источник
0

Попробуйте, у меня это работает.

^(00|\+)[1-9]{1}([0-9][\s]*){9,16}$
Абдул Ахмад Матин
источник
0

Я сделал регулярное выражение для европейских телефонных номеров, и оно зависит от префикса набора и длины номера.

const PhoneEuropeRegExp = () => {
    // eu phones map https://en.wikipedia.org/wiki/Telephone_numbers_in_Europe
    const phonesMap = {
        "43": [4, 13],
        "32": [8, 10],
        "359": [7, 9],
        "385": [8, 9],
        "357": 8,
        "420": 9,
        "45": 8,
        "372": 7,
        "358": [5, 12],
        "33": 9,
        "350": 8,
        "49": [3, 12],
        "30": 10,
        "36": [8, 9],
        "354": [7, 9],
        "353": [7, 9],
        "39": [6, 12],
        "371": 8,
        "423": [7, 12],
        "370": 8,
        "352": 8,
        "356": 8,
        "31": 9,
        "47": [4, 12],
        "48": 9,
        "351": 9,
        "40": 9,
        "421": 9,
        "386": 8,
        "34": 9,
        "46": [6, 9],
    };
    const regExpBuilt = Object.keys(phonesMap)
        .reduce(function(prev, key) {
            const val = phonesMap[key];
            if (Array.isArray(val)) {
                prev.push("(\\+" + key + `[0-9]\{${val[0]},${val[1]}\})`);
            } else {
                prev.push("(\\+" + key + `[0-9]\{${val}\})`);
            }
            return prev;
        }, [])
        .join("|");
    return new RegExp(`^(${regExpBuilt})$`);
};

alert(PhoneEuropeRegExp().test("+420123456789"))
Luky
источник
-4

Попробуй, не знаю, есть ли номер телефона длиннее 12:

^(00|\+){1}\d{12}$
MKYuones
источник
1
Это соответствует числам, состоящим из 12 цифр, включая код страны. Это неверно, потому что он не учитывает изменчивость длины во всем мире. Причем максимальная длина фактически составляет 15 цифр .
TMT
1
@tmt А что ^(00|\+){1}\d{12,15}$тогда?
проверено turing