Jakie wyrażenie regularne będzie pasowało do ważnych międzynarodowych numerów telefonów?

113

Muszę sprawdzić, czy numer telefonu jest prawidłowy, zanim spróbuję go wybrać. Rozmowa telefoniczna może dotrzeć do dowolnego miejsca na świecie.

Jakie wyrażenie regularne będzie pasowało do ważnych międzynarodowych numerów telefonów?

Abtin Forouzandeh
źródło
W jaki sposób dowolne wyrażenie regularne obsługuje błędy, takie jak numery poza usługą? Po prostu spróbuj zadzwonić i obsłużyć nieprawidłowy numer, tak jak inne błędy.
3
Chociaż masz rację, że wyrażenie regularne nie może tego określić, każda próba wychodząca pochłania czas i zasoby. Szybkie sprawdzenie poprawności numeru zapewnia, że ​​oczywiście fałszywe połączenie nie blokuje cennego kanału.
Abtin Forouzandeh
1
LOL @ paxdiablo .... Myślę, że 1-800-CALL-HELP zda twój test RegExp ... lol
Buhake Sindi
1
Coś, co nie jest jasne w tym pytaniu, dotyczy tego, czy numery muszą być ważne, jeśli są wywoływane z USA lub z dowolnego kraju na świecie, ponieważ większość poniższych rozwiązań nie weryfikuje niektórych prawidłowych numerów (takich jak 0030 210 12312312 - ważny Grecki numer
dzwoniony
1
@JonHanna Zgadzam się z pewnym punktem, ale z drugiej strony, z perspektywy UX, czy nie uważasz, że jeśli użytkownik wprowadzi numer 00XX ... X, test powinien przejść? Są przypadki, w których użytkownicy (np. Osoby starsze) nawet nie wiedzą, co to jest + i jak go wpisać na klawiaturze numerycznej / telefonu. Mogę też nadal argumentować, że 00XXX to prawidłowy numer międzynarodowy (tj. W kontekście użytkownika), w którym zamiast + zastosowano kod zakończenia.
Xeroxoid

Odpowiedzi:

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}$

To prawidłowy format dopasowania ogólnego międzynarodowego numeru telefonu. Zastąpiłem międzynarodowy kod dostępu 011 do linii stacjonarnych w Stanach Zjednoczonych standardowym międzynarodowym kodem dostępu „+”, co czyni go obowiązkowym. Zmieniłem też minimum dla numeru krajowego na co najmniej jedną cyfrę.

Pamiętaj, że jeśli wprowadzisz liczby w tym formacie do swojej książki adresowej telefonu komórkowego, możesz z powodzeniem zadzwonić na dowolny numer z książki adresowej, bez względu na to, dokąd podróżujesz. W przypadku telefonów stacjonarnych znak plus należy zastąpić międzynarodowym kodem dostępu kraju, z którego dzwonisz.

Należy pamiętać, że NIE bierze to pod uwagę zasad krajowego planu numeracyjnego - w szczególności dopuszcza zera i jedynki w lokalizacjach, na które krajowe plany numeracyjne mogą nie zezwalać, a także dopuszcza długości numerów większe niż krajowe plany numeracyjne dla niektórych krajów (np. USA).

Eric
źródło
5
Wydaje mi się to rozsądne.
Użyję
17
To nie jest ważne. Europejskie numery telefonów mogą zaczynać się od podwójnego 0 bez znaku + na początku. Tak więc numer telefonu, taki jak: +44 8984 1234 (Wielka Brytania) jest również całkowicie ważny, jeśli zostanie zapisany jako 0044 8984 1234, którego to wyrażenie regularne (a także w przypadku innych odpowiedzi) nie obsługuje.
Xeroxoid
4
W połączeniu z ulepszeniami @ fezfox (?) I zoptymalizowaną długością:^\+((?: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. Z punktu widzenia UX, tak, to może mieć sens, aby pozwolić 00z przodu. Z punktu widzenia programowania i konserwacji, powiedziałbym, że całkowicie w porządku jest wymuszanie wszystkich liczb na początku +lub nawet zastępowanie ich 00za +każdym razem, gdy je otrzymujesz - zwłaszcza biorąc pod uwagę, że większość ludzi jest świadoma +formatu (który z większości międzynarodowych pól wprowadzania numeru telefonu wymagają mimo wszystko). Poza tym jest to poprawka w jednej linii i znacznie bardziej czytelna. Takie podejście zapewniłoby również, że wszystkie numery telefonów mają ten sam format i sprawi, że walidacja będzie znacznie mniej podatna na błędy, dzięki czemu całość będzie łatwiejsza w utrzymaniu.
milosmns
1
A także, w "starych" czasach SMS-ów typu pre-EDGE (zwykły GSM), używanie 00nie wysyłałoby wiadomości poprawnie, podczas gdy rozpoczynanie od a +zawsze działało na całym świecie. Możemy oszaleć i uczynić to super złożonym, ale czasami można / warto porzucić kilka ograniczeń, aby ułatwić sobie życie :)
milosmns
66

Wszystkie kody krajów są zdefiniowane przez ITU. Poniższe wyrażenie regularne jest oparte na ITU-T E.164 i Aneksie do Biuletynu Operacyjnego ITU nr 930 - 15.IV.2009 . Zawiera wszystkie aktualne kody krajów i kody zarezerwowane do wykorzystania w przyszłości. Chociaż można go trochę skrócić, zdecydowałem się dołączyć każdy kod niezależnie.

Dotyczy to połączeń wychodzących z USA. W przypadku innych krajów zamień międzynarodowy kod dostępu (011 na początku wyrażenia regularnego) na dowolny odpowiedni dla planu numeracyjnego tego kraju .

Należy również zauważyć, że ITU E.164 definiuje maksymalną długość pełnego międzynarodowego numeru telefonu do 15 cyfr. Oznacza to, że trzycyfrowy kod kraju daje do 12 dodatkowych cyfr, a jednocyfrowy kod kraju może zawierać do 14 dodatkowych cyfr. Stąd

[0-9]{0,14}$

a koniec wyrażenia regularnego.

Co najważniejsze, to wyrażenie regularne nie oznacza, że ​​numer jest ważny - każdy kraj definiuje swój własny wewnętrzny plan numeracji. To tylko gwarantuje, że kod kraju jest ważny.

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} $

Abtin Forouzandeh
źródło
12
Prawie miał rację… „011” nie jest częścią międzynarodowego kodu. Właśnie tego potrzebują ludzie w USA, aby wykonać połączenie międzynarodowe. Ten prefiks zmieni się w zależności od tego, skąd dzwonisz ... Więc ten prefiks NIE jest częścią numeru.
Gabriel Magana,
3
@gmagana - Wspominam o tym w mojej odpowiedzi (akapit 2)
Abtin Forouzandeh
1
Chodzi mi o to, że nie jest to część numeru telefonu. To tak, jakby powiedzieć, że prefiks krajowego numeru zamiejscowego „1” jest częścią numeru telefonu.
Gabriel Magana
1
@gmagana - chociaż masz rację, że nie jest to część numeru telefonu, to jest technicznie wymagane do wykonania połączenia.
Abtin Forouzandeh
2
@Roger Pate: Spędziłem trochę czasu, zastanawiając się nad tym i mam nadzieję, że przyda się to innym. Miałem też nadzieję, że ktoś inny może mieć lepsze rozwiązanie (dlatego nie oznaczyłem własnej odpowiedzi jako zaakceptowaną).
Abtin Forouzandeh
32

To jest dalsza optymalizacja.

\+(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) dopuszcza ważne międzynarodowe prefiksy
(ii), po których następuje 9 lub 10 cyfr, z dowolnym rodzajem lub umiejscowieniem ograniczników (z wyjątkiem między dwiema ostatnimi cyframi)

To będzie pasować:
+ 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
źródło
Wiem, że to stara odpowiedź, ale czy jest jakaś opcja, aby cyfra 1 była opcjonalna dla liczb amerykańskich?
Adam Fratino
To, co chcesz zrobić, to (i) uczynić „+” opcjonalnym i (ii) opcjonalnym kodem międzynarodowym. Więc umieść „?” po znaku + i po pierwszym nawiasie zamykającym.
fezfox
@ManosPasgiannis cóż, tak, jak określono „po czym następuje 9 lub 10 cyfr”. Na Cyprze pojawiłby się 8, więc po prostu dostosuj ostatnią sekwencję, usuwając raz wystąpienie \ d \ W * i wykonaj ostatnie wyrażenie (\ d {1,3})
fezfox
22

Możesz skorzystać z biblioteki libphonenumber firmy 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();
    }
Paulo Fidalgo
źródło
2
To mogłoby być dobre rozwiązanie, ale aby sprawdzić numery telefonów, przed skorzystaniem z tej biblioteki musisz zaimportować ogromną ilość js ... ponieważ libphonenumber.js wymaga biblioteki zamykania ... to nie jest lekkie rozwiązanie: /
J. BizMai
11

To zadziała w przypadku numerów międzynarodowych;

DO#:

@"^((\+\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
źródło
11

Używam tego:

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

Zalety: rozpoznaje początki + lub 011, pozwala na tak długo, jak potrzeba i obsługuje wiele konwencji rozszerzeń. (#, x, ext, extension)

TOBlender
źródło
Ten jest bardzo zbliżony do większości międzynarodowych formatów numerów telefonów.
feeela
9

Oto „zoptymalizowana” wersja Twojego wyrażenia regularnego:

^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}$

Możesz zamienić \ds na, [0-9]jeśli twoja składnia wyrażeń regularnych nie obsługuje \d.

Laurence Gonsalves
źródło
7

W przypadku iOS SWIFT uznałem to za pomocne,

let phoneRegEx = "^((\\+)|(00)|(\\*)|())[0-9]{3,14}((\\#)|())$"
Mohammad Zaid Pathan
źródło
nie udało się zdobyć +91 9999999999
Sahil Mahajan
6

Zmodyfikowane wyrażenie regularne @ Erica - dodano listę wszystkich kodów krajów ( pobrane z xxxdepy @ Github . Mam nadzieję, że okażą się pomocne:

/(\+|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
źródło
Działa jak marzenie. Również dla holenderskich numerów telefonów. Dzięki!
mauvm
2

Jest oczywiście wiele sposobów, aby to zrobić, o czym świadczą wszystkie odpowiedzi udzielone do tej pory, ale wrzucę tutaj moją wartość 0,02 USD i przedstawię poniżej wyrażenie regularne, które jest nieco bardziej zwięzłe niż prawie wszystkie powyższe , ale dokładniej niż większość. Ma również fajny efekt uboczny polegający na pozostawieniu kodu kraju w 1 USD i numeru lokalnego w 2 USD.

^ \ + (? = \ 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 +) $

trekinaz
źródło
2

Bez krytykowania tych wspaniałych odpowiedzi, chcę tylko przedstawić proste rozwiązanie, którego używam dla naszych twórców treści dla administratorów:

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

Siła zacznij od plusa lub dwóch zer i użyj przynajmniej trochę liczb, spacji, nawiasów klamrowych, minus i kropki są opcjonalne i nie ma innych znaków. Możesz bezpiecznie usunąć wszystkie nie-liczby i użyć tego w tel: input. Liczby będą miały wspólną formę reprezentacji i nie muszę się martwić, że będę zbyt restrykcyjny.

Blackbam
źródło
1

Prosta wersja dla numerów europejskich, która pasuje do numerów takich jak 0034617393211, ale także długich, takich jak 004401484172842.

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

Mam nadzieję, że to pomoże :·)

Roc Boronat
źródło
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
źródło
1
Chociaż ten fragment kodu może odpowiedzieć na pytanie, nie zapewnia żadnego kontekstu wyjaśniającego, jak i dlaczego. Rozważ dodanie jednego lub dwóch zdań, aby wyjaśnić swoją odpowiedź.
brandonscript
1

Oto wyrażenie regularne dla następujących najbardziej typowych scenariuszy numerów telefonów. Chociaż jest to dostosowane z perspektywy USA dla numerów kierunkowych, działa w scenariuszach międzynarodowych.

  1. Rzeczywista liczba powinna składać się tylko z 10 cyfr.
  2. W przypadku numerów w USA numer kierunkowy może być ujęty w nawiasy ().
  3. Kod kraju może mieć od 1 do 3 cyfr. Opcjonalnie może być poprzedzony znakiem +.
  4. Pomiędzy kodem kraju, numerem kierunkowym a resztą numeru mogą występować myślniki, spacje, kropki lub nie mogą być spacje.
  5. Prawidłowy numer telefonu nie może składać się z samych zer.

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

Wyjaśnienie:

    ^ - 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

Więcej przykładów i wyjaśnień - https://regex101.com/r/hTH8Ct/2/

Appy
źródło
1

Użyłem tego poniżej:

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

Format + CCC.NNNNNNNNNNxEEE lub 00CCC.NNNNNNNNNNxEEEE

Numer telefonu musi zaczynać się od „+” lub „00” w przypadku połączenia międzynarodowego. gdzie C to 1–3 cyfrowy kod kraju,

N ma maksymalnie 14 cyfr,

a E to (opcjonalne) rozszerzenie.

Początkowy znak plus i kropka po kodzie kraju są wymagane. Literalny znak „x” jest wymagany tylko wtedy, gdy podano rozszerzenie.

Rousonur Jaman
źródło
0

Międzynarodowy plan numeracji jest oparty na ITU E.164 planie numeracji . Myślę, że to jest punkt wyjścia dla twojego wyrażenia regularnego.

Zaktualizuję to, jeśli obejdę się, aby utworzyć wyrażenie regularne na podstawie numeracji ITU E.164.

Buhake Sindi
źródło
0

To wyrażenie Regex działa dla numerów telefonów Indii, Kanady, Europy, Nowej Zelandii, Australii i Stanów Zjednoczonych wraz z ich kodami krajów:

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

Harsha Garg
źródło
0

To działa dla mnie, ale bez prefiksu 00, 001, 0011 itp .:

/^\+*(\d{3})*[0-9,\-]{8,}/
redwud
źródło
0

Spróbuj tego, to działa dla mnie.

^(00|\+)[1-9]{1}([0-9][\s]*){9,16}$
AbdulAhmad Matin
źródło
0

Stworzyłem wyrażenie regularne dla europejskich numerów telefonów i jest ono specyficzne dla prefiksu wybierania względem długości numeru.

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"))
letni
źródło
-4

Spróbuj tego, nie wiem, czy istnieje numer telefonu dłuższy niż 12:

^(00|\+){1}\d{12}$
MKYuones
źródło
1
Odpowiada to liczbom, które mają dokładnie 12 cyfr, łącznie z kodem kraju. To jest złe, ponieważ nie uwzględnia zmienności długości na całym świecie. Ponadto maksymalna długość to w rzeczywistości 15 cyfr .
tmt
1
@tmt A co powiesz na ^(00|\+){1}\d{12,15}$to?
turingtestowane