Ekspresi reguler apa yang cocok dengan nomor telepon internasional yang valid?

113

Saya perlu menentukan apakah nomor telepon valid sebelum mencoba memanggilnya. Panggilan telepon bisa pergi ke mana saja di dunia.

Ekspresi reguler apa yang cocok dengan nomor telepon internasional yang valid?

Abtin Forouzandeh
sumber
Bagaimana regex menangani kesalahan seperti nomor layanan? Coba saja menelepon dan menangani nomor yang tidak valid seperti yang Anda lakukan pada kesalahan lainnya.
3
Meskipun Anda benar bahwa regex tidak dapat menentukan ini, setiap upaya keluar menghabiskan waktu dan sumber daya. Melakukan pemeriksaan kewarasan cepat pada nomor tersebut memastikan bahwa panggilan yang jelas-jelas palsu tidak memblokir saluran yang berharga.
Abtin Forouzandeh
1
LOL @ paxdiablo .... Saya kira 1-800-CALL-HELP akan lulus tes RegExp Anda ... lol
Buhake Sindi
1
Sesuatu yang tidak jelas dalam pertanyaan ini adalah apakah nomor tersebut harus valid jika dipanggil dari AS atau dari negara mana pun di dunia, karena sebagian besar solusi di bawah tidak memvalidasi beberapa nomor yang valid (seperti 0030 210 12312312 - valid Nomor Yunani yang dihubungi dari negara UE mana pun)
Xeroxoid
1
@JonHanna Saya setuju satu hal, tetapi di sisi lain, dari perspektif UX tidakkah Anda berpikir bahwa jika pengguna memasukkan nomor 00XX ... X, tes harus lulus? Ada kasus di mana pengguna (yaitu orang yang lebih tua) bahkan tidak tahu apa itu + dan bagaimana cara mengetiknya pada keypad numerik / telepon. Juga saya masih bisa berargumen bahwa 00XXX adalah nomor internasional yang valid (yaitu dalam konteks pengguna) di mana alih-alih +, kode keluar digunakan.
Xeroxoid

Jawaban:

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

Apakah format yang benar untuk mencocokkan nomor telepon internasional generik. Saya mengganti kode akses internasional terpusat saluran darat AS 011 dengan pengenal kode akses internasional standar '+', sehingga wajib. Saya juga mengubah minimum untuk nomor nasional menjadi setidaknya satu digit.

Perhatikan bahwa jika Anda memasukkan nomor dalam format ini ke dalam buku alamat ponsel Anda, Anda mungkin berhasil memanggil nomor apa pun di buku alamat Anda ke mana pun Anda bepergian. Untuk jalur darat, ganti plus dengan kode akses internasional untuk negara tempat Anda melakukan panggilan.

Perhatikan bahwa ini TIDAK memperhitungkan aturan nomor rencana nasional - khususnya, ini memungkinkan angka nol dan satu di lokasi yang mungkin tidak diizinkan oleh rencana nomor nasional dan juga memungkinkan panjang nomor lebih besar dari rencana nomor nasional untuk beberapa negara (misalnya, AS).

Eric
sumber
5
Sepertinya masuk akal bagi saya. Saya akan menggunakan yang ini
Sevenearths
17
Ini tidak valid Nomor telepon Eropa dapat dimulai dengan angka ganda 0 tanpa + di awal. Jadi nomor telepon seperti: +44 8984 1234 (UK) juga valid jika ditulis 0044 8984 1234 yang tidak didukung oleh regexp ini (dan juga jawaban lain).
Xeroxoid
4
Dikombinasikan dengan peningkatan @ fezfox (?) Dan panjang dioptimalkan:^\+((?: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. Dari sudut pandang UX, ya mungkin masuk akal untuk mengizinkannya 00di depan. Dari sudut pandang pengembangan dan pemeliharaan, menurut saya tidak masalah untuk menerapkan semua nomor untuk memulai +atau bahkan mengganti 00dengan +setiap kali Anda mendapatkannya - terutama mengingat bahwa kebanyakan orang mengetahui +formatnya (yang sebagian besar bidang input telepon internasional membutuhkan). Selain itu, ini adalah perbaikan satu baris, dan jauh lebih mudah dibaca. Pendekatan ini juga akan memastikan bahwa semua nomor telepon dalam format yang sama, dan membuat validasi Anda tidak terlalu rentan terhadap kesalahan, sehingga semuanya lebih dapat dipelihara.
milosmns
1
Dan juga, di masa "lama" dari SMS pra-EDGE (GSM biasa), penggunaan 00tidak akan mengirim pesan dengan benar, sedangkan memulai dengan a +akan selalu berfungsi secara internasional. Kita bisa menjadi gila dan membuatnya super kompleks, tapi terkadang mungkin / layak untuk
menghilangkan
66

Semua kode negara ditentukan oleh ITU. Regex berikut didasarkan pada ITU-T E.164 dan Lampiran Buletin Operasional ITU No. 930 - 15.IV.2009 . Ini berisi semua kode negara saat ini dan kode yang disediakan untuk penggunaan masa depan. Meskipun bisa sedikit dipersingkat, saya memutuskan untuk memasukkan setiap kode secara independen.

Ini untuk panggilan yang berasal dari AS. Untuk negara lain, ganti kode akses internasional (011 di awal regex) dengan apapun yang sesuai untuk rencana panggilan negara tersebut .

Juga, perhatikan bahwa ITU E.164 menetapkan panjang maksimum dari sebuah nomor telepon internasional lengkap menjadi 15 digit. Ini berarti kode negara tiga digit menghasilkan hingga 12 digit tambahan, dan kode negara 1 digit dapat berisi hingga 14 digit tambahan. Oleh karena itu

[0-9]{0,14}$

akhir ekspresi reguler.

Yang terpenting, regex ini tidak berarti nomor tersebut valid - setiap negara menetapkan rencana penomoran internalnya sendiri. Ini hanya memastikan bahwa kode negara valid.

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
sumber
12
Hampir benar ... "011" bukan bagian dari kode internasional. Itulah yang perlu dilakukan orang di AS untuk melakukan panggilan internasional. Awalan itu akan berubah tergantung dari mana Anda menelepon ... Jadi, awalan itu BUKAN bagian dari nomor tersebut.
Gabriel Magana
3
@gmagana - Saya menyebutkan itu dalam jawaban saya (paragraf 2)
Abtin Forouzandeh
1
Maksud saya, ini bukan bagian dari nomor telepon. Itu seperti mengatakan awalan panggilan jarak jauh nasional AS "1" adalah bagian dari nomor telepon.
Gabriel Magana
1
@gmagana - meskipun Anda benar bahwa itu bukan bagian dari nomor telepon, secara teknis diperlukan untuk melakukan panggilan.
Abtin Forouzandeh
2
@Roger Pate: Saya menghabiskan sedikit waktu untuk memikirkannya dan saya berharap ini akan berguna bagi orang lain. Saya juga berharap bahwa orang lain mungkin memiliki solusi yang lebih baik (itulah sebabnya saya belum menandai jawaban saya sendiri sebagai diterima).
Abtin Forouzandeh
32

Ini adalah pengoptimalan lebih lanjut.

\+(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) memperbolehkan prefiks internasional yang valid
(ii) diikuti dengan 9 atau 10 digit, dengan tipe atau penempatan delimeter apa pun (kecuali antara dua digit terakhir)

Ini akan cocok dengan:
+ 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.dll
sumber
Saya tahu ini adalah jawaban lama, tetapi apakah ada opsi untuk menjadikan 1 opsional untuk nomor Amerika?
Adam Fratino
Apa yang ingin Anda lakukan adalah (i) membuat "+" opsional dan (ii) kode internasional opsional. Jadi tempat "?" setelah + dan setelah braket tutup pertama.
fezfox
@ManosPasgiannis ya, seperti yang ditentukan "diikuti dengan 9 atau 10 digit". Ini akan muncul di siprus Anda menggunakan 8, jadi sesuaikan saja urutan terakhir dengan menghapus satu kali contoh \ d \ W * dan buat ekspresi terakhir (\ d {1,3})
fezfox
22

Anda dapat menggunakan libphonenumber perpustakaan dari 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
sumber
2
Ini bisa menjadi solusi yang baik tetapi hanya untuk memeriksa nomor telepon, sebelum menggunakan perpustakaan ini, Anda harus mengimpor sejumlah besar js ... karena libphonenumber.js membutuhkan perpustakaan penutupan ... ini bukan solusi yang mudah: /
J. BizMai
11

Ini akan berfungsi untuk nomor internasional;

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
sumber
11

Saya menggunakan yang ini:

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

Keuntungan: mengenali awal + atau 011, membiarkannya selama diperlukan, dan menangani banyak konvensi ekstensi. (#, x, ext, ekstensi)

TOBlender
sumber
Yang ini hampir sama dengan kebanyakan format nomor telepon internasional.
feeela
9

Berikut adalah versi regex Anda yang "dioptimalkan":

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

Anda dapat mengganti \ds dengan [0-9]jika sintaks regex Anda tidak mendukung \d.

Laurence Gonsalves
sumber
7

Untuk iOS SWIFT menurut saya ini berguna,

let phoneRegEx = "^((\\+)|(00)|(\\*)|())[0-9]{3,14}((\\#)|())$"
Mohammad Zaid Pathan
sumber
gagal untuk +91 9999999999
Sahil Mahajan
6

Modifikasi ekspresi reguler @ Eric - menambahkan daftar semua kode negara (mendapatkannya dari xxxdepy @ Github . Saya harap Anda akan merasakan manfaatnya :

/(\+|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
sumber
Bekerja seperti pesona. Untuk nomor telepon Belanda juga. Terima kasih!
mauvm
2

Jelas ada banyak cara untuk melakukan ini, sebagaimana dibuktikan oleh semua jawaban berbeda yang diberikan sejauh ini, tetapi saya akan memberikan nilai $ 0,02 saya di sini dan memberikan regex di bawah, yang sedikit lebih singkat daripada hampir semua jawaban di atas , tapi lebih teliti dari kebanyakan juga. Ini juga memiliki efek samping yang bagus dengan meninggalkan kode negara di $ 1 dan nomor lokal di $ 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 +) $

trekinaz
sumber
2

Tidak ada kritik mengenai jawaban hebat itu, saya hanya ingin menyajikan solusi sederhana yang saya gunakan untuk admin pembuat konten kami:

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

Paksa mulai dengan plus atau dua nol dan gunakan setidaknya sedikit angka, spasi, tanda kurung, minus dan titik adalah opsional dan tidak ada karakter lain. Anda dapat dengan aman menghapus semua non-angka dan menggunakannya di tel: input. Angka akan memiliki bentuk representasi yang sama dan saya tidak perlu khawatir akan membatasi.

Blackbam
sumber
1

Versi sederhana untuk angka eropa, yang cocok dengan angka seperti 0034617393211 tetapi juga angka yang panjang seperti 004401484172842.

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

Semoga membantu: ·)

Roc Boronat
sumber
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
sumber
1
Meskipun cuplikan kode ini dapat menjawab pertanyaan tersebut, cuplikan kode ini tidak memberikan konteks apa pun untuk menjelaskan bagaimana atau mengapa. Pertimbangkan untuk menambahkan satu atau dua kalimat untuk menjelaskan jawaban Anda.
brandonscript
1

Berikut ini regex untuk skenario nomor telepon paling umum berikut. Meskipun ini disesuaikan dari perspektif AS untuk kode area, ini berfungsi untuk skenario internasional.

  1. Angka sebenarnya harus 10 digit saja.
  2. Untuk nomor AS, kode area dapat diapit dengan tanda kurung ().
  3. Kode negara dapat terdiri dari 1 hingga 3 digit. Secara opsional dapat diawali dengan tanda +.
  4. Mungkin ada tanda hubung, spasi, titik, atau tanpa spasi di antara kode negara, kode area, dan nomor lainnya.
  5. Nomor telepon yang valid tidak boleh semuanya nol.

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

Penjelasan:

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

Contoh dan penjelasan lainnya - https://regex101.com/r/hTH8Ct/2/

Appy
sumber
1

Saya telah menggunakan ini di bawah ini:

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

Format + CCC.NNNNNNNNNNxEEEE atau 00CCC.NNNNNNNNNNxEEEE

Nomor telepon harus dimulai dengan '+' atau '00' untuk panggilan internasional. dengan C adalah 1–3 digit kode negara,

N sampai 14 digit,

dan E adalah ekstensi (opsional).

Diperlukan tanda plus dan titik setelah kode negara. Karakter "x" literal diperlukan hanya jika ekstensi disediakan.

Rousonur Jaman
sumber
0

Rencana penomoran internasional didasarkan pada ITU E.164 rencana penomoran . Saya rasa itulah titik awal ekspresi reguler Anda.

Saya akan memperbarui ini jika saya sempat membuat ekspresi reguler berdasarkan penomoran ITU E.164.

Buhake Sindi
sumber
0

Ekspresi Regex ini berfungsi untuk nomor telepon India, Kanada, Eropa, Selandia Baru, Australia, Amerika Serikat, bersama dengan kode negaranya:

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

Harsha Garg
sumber
0

Ini bekerja untuk saya, tanpa awalan 00, 001, 0011 dll:

/^\+*(\d{3})*[0-9,\-]{8,}/
redwud
sumber
0

Coba ini, ini berhasil untuk saya.

^(00|\+)[1-9]{1}([0-9][\s]*){9,16}$
AbdulAhmad Matin
sumber
0

Saya membuat regexp untuk nomor telepon Eropa, dan ini khusus untuk awalan panggilan vs panjang nomor.

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
sumber
-4

Coba ini, saya tidak tahu apakah ada nomor telepon yang lebih panjang dari 12:

^(00|\+){1}\d{12}$
MKYuones
sumber
1
Ini cocok dengan nomor yang memiliki tepat 12 digit termasuk kode negaranya. Itu salah karena tidak memperhitungkan variabilitas panjang di seluruh dunia. Apalagi panjang maksimal sebenarnya 15 digit .
tmt
1
@tmt Bagaimana kalau ^(00|\+){1}\d{12,15}$begitu?
diuji