Який регулярний вираз відповідатиме дійсним міжнародним телефонним номерам?


113

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

Який регулярний вираз відповідатиме дійсним міжнародним телефонним номерам?


Як будь-яка регулярна виразка обробляє помилки, як-от службові номери? Просто спробуйте зателефонувати та обробити недійсний номер, як і інші помилки.

3
Незважаючи на те, що регулярний вираз не може цього визначити, кожна вихідна спроба вимагає часу та ресурсів. Швидка перевірка чистоти номера гарантує, що очевидно неправдивий дзвінок не блокує цінний канал.
Абтін Форузанде

1
LOL @ paxdiablo .... Я думаю, 1-800-CALL-HELP
здасть

1
У цьому питанні щось незрозуміле - це чи повинні бути чинні цифри, якщо вони дзвонять із США чи з будь-якої країни світу, тому що більшість із наведених нижче рішень не підтверджують дійсні цифри (наприклад, 0030 210 12312312 - дійсне Грецький номер зателефонували з будь-якої країни ЄС)
Xeroxoid

1
@JonHanna Я погоджуюся на точку, але з іншого боку, з точки зору UX, ви не думаєте, що якщо користувач введе номер 00XX ... X, тест повинен пройти? Бувають випадки, коли користувачі (тобто люди похилого віку) навіть не знають, що таке +, і як набрати його на цифровій / телефонній клавіатурі. Також я все ще можу стверджувати, що 00XXX - це дійсний міжнародний номер (тобто в контексті користувача), де замість + використовується код виходу.
Ксероксоїд

Відповіді:


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
Мені здається розумним. Я буду використовувати цей
Sevenearths

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

1
+1. З точки зору UX, так, це може мати сенс дозволити 00попереду. З точки зору розробки та технічного обслуговування, я б сказав, що цілком чудово застосовувати всі номери, починаючи з +або навіть замінюючи 00їх +щоразу, коли ви їх отримуєте - особливо, враховуючи, що більшість людей знають про +формат (який більшість міжнародних полів введення телефонів вимагати все одно). Плюс це виправлення з одного вкладиша та набагато зручніше для читання. Такий підхід також гарантує, що всі телефонні номери мають однаковий формат, і робить вашу перевірку значно меншою, ніж схильність до помилок.
milosmns

1
Крім того, у "старі" дні перед EDGE (звичайний GSM) SMS, використання 00не надсилало б повідомлення правильно, тоді як початок з "A" +завжди працюватиме на міжнародному рівні. Ми можемо зійти з розуму і зробити це надзвичайно складним, але іноді можливо / варто скинути кілька обмежень, щоб полегшити наше життя :)
milosmns

66

Усі коди країн визначаються МСЕ. Наступний регекс базується на МСЕ-T E.164 та додатку до Оперативного вісника МСЕ № 930 - 15.IV.2009 . Він містить усі поточні коди країн та коди, зарезервовані для подальшого використання. Хоча це можна було трохи скоротити, я вирішив включити кожен код самостійно.

Це для дзвінків із США. Для інших країн замініть міжнародний код доступу (011 на початку регулярного виразу) на той, що підходить для плану набору цієї країни. .

Також зауважте, що МСЕ E.164 визначає максимальну довжину повного міжнародного телефонного номера до 15 цифр. Це означає, що тризначний код країни приводить до 12 додаткових цифр, а 1-значний код країни може містити до 14 додаткових цифр. Отже

[0-9]{0,14}$

a кінець регулярного вираження.

Найголовніше, що цей регулярний вираз не означає, що число є дійсним - кожна країна визначає свій внутрішній план нумерації. Це лише гарантує, що код країни дійсний.

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 - хоча ви маєте рацію, що це не номер телефону, технічно потрібно зателефонувати.
Абтін Форузанде

2
@Roger Pate: Я витратив трохи часу, розбираючись у цьому, і сподіваюся, що це стане в нагоді іншим. Я також сподівався, що хтось інший може мати краще рішення (саме тому я не позначив власну відповідь прийнятою).
Абтін Форузанде

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


Я знаю, що це стара відповідь, але чи є можливість зробити 1 необов’язковим для американських номерів?
Адам Фратино

Що ви хочете зробити, це (i) зробити "+" необов'язковим та (ii) міжнародним кодом необов'язковим. Так місце "?" після + та після першого закритого дужки.
fezfox

@ManosPasgiannis також так, як зазначено "з наступними 9 або 10 цифрами". Це з'явиться у використанні цитрусу 8, тому просто відрегулюйте останню послідовність, видаливши один раз екземпляр \ d \ W * і зробіть останній вираз (\ d {1,3})
fezfox

22

Ви можете використовувати бібліотечний номер бібліотеки від 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 потребує бібліотеки закриття ... це не легке рішення: /
Дж. 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}$/

11

Я використовую цей:

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

Переваги: ​​розпізнає початки + або 011, дозволяє бути довгим, наскільки це потрібно, і обробляє безліч угод про розширення. (#, x, ext, розширення)


Це дуже близький до більшості міжнародних форматів телефонних номерів.
таксаела

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.



6

Модифікований регулярний вираз @ Еріка - додав список усіх кодів країн (отримав їх від 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}$/

Працює як шарм. Для голландських номерів телефонів. Дякую!
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:. Цифри матимуть загальну форму представлення, і мені не потрібно турбуватися про обмеження.


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();
}

1
Хоча цей фрагмент коду може відповісти на запитання, він не містить жодного контексту, щоб пояснити, як і чому. Подумайте про додавання речення чи двох, щоб пояснити свою відповідь.
брендоскрипт

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/


1

Я використовував це нижче:

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

Формат + CCC.NNNNNNNNNNxEEEE або 00CCC.NNNNNNNNNxEEEE

Номер телефону повинен починатися з "+" або "00" для міжнародного дзвінка. де C - 1–3-значний код країни,

N - 14 цифр,

і E - (необов'язково) розширення.

Потрібний знак плюс і крапка, що слідує за кодом країни, обов'язкові. Буквальний символ "x" потрібен лише в тому випадку, якщо надано розширення.



0

План міжнародного нумерації базується на МСЕ E.164 плані нумерації . Я думаю, що це відправна точка для вашого регулярного вираження.

Я оновлю це, якщо обійдуся, щоб створити регулярний вираз на основі нумерації ITU E.164.


0

Ця програма Regex Expression працює для телефонів Індії, Канади, Європи, Нової Зеландії, Австралії, Сполучених Штатів Америки, а також кодів їх країн:

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





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"))

-4

Спробуйте це, я не знаю, чи є номер телефону довше 12:

^(00|\+){1}\d{12}$

1
Це збігається з цифрами, які мають точно 12 цифр, включаючи код країни. Це неправильно, оскільки він не враховує змінну довжини в усьому світі. Причому максимальна довжина насправді становить 15 цифр .
tmt

1
@tmt Як ^(00|\+){1}\d{12,15}$тоді?
turingtest
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.