Biểu thức chính quy nào sẽ khớp với số điện thoại quốc tế hợp lệ?


113

Tôi cần xác định xem một số điện thoại có hợp lệ hay không trước khi thử quay số đó. Cuộc gọi điện thoại có thể đi bất cứ nơi nào trên thế giới.

Biểu thức chính quy nào sẽ khớp với số điện thoại quốc tế hợp lệ?


Làm thế nào để bất kỳ regex nào xử lý các lỗi như hết số dịch vụ? Chỉ cần thử gọi và xử lý số không hợp lệ như bạn làm với các lỗi khác.

3
Mặc dù bạn nói đúng rằng regex không thể xác định điều này, nhưng mỗi nỗ lực gửi đi sẽ tiêu tốn thời gian và tài nguyên. Kiểm tra nhanh số điện thoại này đảm bảo rằng một cuộc gọi không có thật sẽ không chặn một kênh có giá trị.
Abtin Forouzandeh

1
LOL @ paxdiablo .... Tôi đoán 1-800-CALL-HELP sẽ vượt qua bài kiểm tra RegExp của bạn ... lol
Buhake Sindi

1
Có điều gì đó không rõ ràng trong câu hỏi này là liệu các số phải hợp lệ nếu được gọi từ Hoa Kỳ hoặc từ bất kỳ quốc gia nào trên thế giới, bởi vì hầu hết các giải pháp bên dưới không xác thực một số số hợp lệ (chẳng hạn như 0030 210 12312312 - một hợp lệ Số Hy Lạp được gọi từ bất kỳ quốc gia EU nào)
Xeroxoid

1
@JonHanna Tôi đồng ý một điểm, nhưng mặt khác, từ góc độ người dùng, bạn không nghĩ rằng nếu người dùng nhập số 00XX ... X, thì bài kiểm tra sẽ vượt qua sao? Có những trường hợp người dùng (tức là những người lớn tuổi) thậm chí không biết dấu + là gì và cách nhập nó trên bàn phím số / điện thoại. Ngoài ra, tôi vẫn có thể tranh luận rằng 00XXX là một số quốc tế hợp lệ (tức là trong ngữ cảnh của người dùng) trong đó thay vì +, mã thoát đã được sử dụng.
Xeroxoid

Câu trả lời:


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

Là định dạng chính xác để khớp với một số điện thoại quốc tế chung. Tôi đã thay thế mã truy cập quốc tế tập trung vào đường dây cố định 011 của Hoa Kỳ bằng định danh mã truy cập quốc tế tiêu chuẩn là '+', khiến nó trở thành bắt buộc. Tôi cũng đã thay đổi mức tối thiểu cho số quốc gia thành ít nhất một chữ số.

Lưu ý rằng nếu bạn nhập các số ở định dạng này vào danh bạ điện thoại di động của mình, bạn có thể gọi thành công bất kỳ số nào trong sổ địa chỉ của mình cho dù bạn đi du lịch ở đâu. Đối với đường dây cố định, hãy thay dấu cộng bằng mã truy cập quốc tế cho quốc gia bạn đang gọi.

Lưu ý rằng điều này KHÔNG tính đến các quy tắc của gói số quốc gia - cụ thể, nó cho phép các số không và các số ở những vị trí mà gói số quốc gia có thể không cho phép và cũng cho phép độ dài số lớn hơn gói số quốc gia cho một số quốc gia (ví dụ: Hoa Kỳ).


5
Có vẻ hợp lý với tôi. Tôi sẽ sử dụng cái này
Sevenearths

17
Điều này không hợp lệ. Các số điện thoại ở Châu Âu có thể bắt đầu bằng số 0 kép mà không có dấu + ở đầu. Do đó, một số điện thoại như: +44 8984 1234 (Vương quốc Anh) cũng hoàn toàn hợp lệ nếu được viết 0044 8984 1234 mà regexp này (và trên các câu trả lời khác) không hỗ trợ.
Xeroxoid

4
Kết hợp với những cải tiến của @ fezfox (?) Và độ dài được tối ưu hóa:^\+((?: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. Từ quan điểm của người dùng, vâng, bạn có thể cho phép 00ở phía trước. Từ quan điểm phát triển và bảo trì, tôi muốn nói rằng hoàn toàn tốt khi bắt buộc tất cả các số bắt đầu bằng +hoặc thậm chí thay thế 00bằng một +số mỗi khi bạn lấy nó - đặc biệt là khi hầu hết mọi người đều biết về +định dạng (mà hầu hết các trường nhập điện thoại quốc tế yêu cầu dù sao). Thêm vào đó, nó là một bản sửa lỗi một lớp và dễ đọc hơn. Cách tiếp cận này cũng sẽ đảm bảo rằng tất cả các số điện thoại ở cùng một định dạng và làm cho việc xác thực của bạn ít bị lỗi hơn nhiều, do đó làm cho toàn bộ mọi thứ dễ bảo trì hơn.
milosmns

1
Ngoài ra, trong những ngày "cũ" của SMS trước EDGE (GSM thuần túy), việc sử dụng 00sẽ không gửi được tin nhắn một cách chính xác, trong khi bắt đầu bằng a +sẽ luôn hoạt động trên phạm vi quốc tế. Chúng ta có thể phát điên lên và làm cho nó siêu phức tạp, nhưng đôi khi nó có thể / giá trị thả một vài trở ngại để làm cho cuộc sống của chúng tôi dễ dàng hơn :)
milosmns

66

Tất cả các mã quốc gia được xác định bởi ITU. Bản regex sau đây dựa trên ITU-T E.164 và Phụ lục của Bản tin hoạt động ITU số 930 - 15.IV.2009 . Nó chứa tất cả các mã quốc gia hiện tại và mã được dành để sử dụng trong tương lai. Mặc dù nó có thể được rút ngắn một chút, nhưng tôi quyết định bao gồm từng mã một cách độc lập.

Điều này dành cho các cuộc gọi xuất phát từ Hoa Kỳ. Đối với các quốc gia khác, hãy thay thế mã truy cập quốc tế (011 ở đầu regex) bằng bất kỳ mã nào phù hợp với gói quay số của quốc gia đó .

Ngoài ra, lưu ý rằng ITU E.164 xác định độ dài tối đa của một số điện thoại quốc tế đầy đủ là 15 chữ số. Điều này có nghĩa là mã quốc gia ba chữ số dẫn đến tối đa 12 chữ số bổ sung và mã quốc gia 1 chữ số có thể chứa tối đa 14 chữ số bổ sung. Vì thế

[0-9]{0,14}$

một sự kết thúc của regex.

Quan trọng nhất, regex này không có nghĩa là số hợp lệ - mỗi quốc gia xác định kế hoạch đánh số nội bộ của riêng mình. Điều này chỉ đảm bảo rằng mã quốc gia là hợp lệ.

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
Gần như đã đúng ... "011" không phải là một phần của mã quốc tế. Đó chỉ là những gì mọi người ở Hoa Kỳ cần quay số để thực hiện cuộc gọi quốc tế. Tiền tố đó sẽ thay đổi tùy thuộc vào nơi bạn gọi từ ... Vì vậy, tiền tố đó KHÔNG phải là một phần của số.
Gabriel Magana

3
@gmagana - Tôi kể rằng trong câu trả lời của tôi (đoạn 2)
Abtin Forouzandeh

1
Quan điểm của tôi là nó không phải là một phần của số điện thoại. Điều đó giống như nói tiền tố quay số đường dài quốc gia Hoa Kỳ "1" là một phần của số điện thoại.
Gabriel Magana

1
@gmagana - mặc dù bạn nói đúng rằng nó không phải là một phần của số điện thoại, nhưng về mặt kỹ thuật, nó là bắt buộc để thực hiện cuộc gọi.
Abtin Forouzandeh

2
@Roger Pate: Tôi đã dành một chút thời gian để tìm ra điều này và tôi hy vọng nó sẽ hữu ích cho những người khác. Tôi cũng hy vọng rằng ai đó có thể có một giải pháp tốt hơn (đó là lý do tại sao tôi chưa đánh dấu câu trả lời của chính mình là được chấp nhận).
Abtin Forouzandeh

32

Đây là một tối ưu hóa hơn nữa.

\+(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) cho phép các tiền tố quốc tế hợp lệ
(ii) theo sau là 9 hoặc 10 chữ số, với bất kỳ loại hoặc cách đặt dấu hiệu nào (ngoại trừ giữa hai chữ số cuối cùng)

Điều này sẽ khớp:
+ 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


Tôi biết đây là một câu trả lời cũ, nhưng có tùy chọn nào để đặt số 1 là tùy chọn cho các số Mỹ không?
Adam Fratino

Những gì bạn muốn làm là (i) đặt "+" là tùy chọn và (ii) mã quốc tế là tùy chọn. Vì vậy, nơi "?" sau dấu + và sau dấu ngoặc đóng đầu tiên.
fezfox

@ManosPasgiannis cũng có, như được chỉ định "theo sau là 9 hoặc 10 chữ số". Nó sẽ xuất hiện trong cyprus mà bạn sử dụng 8, vì vậy chỉ cần điều chỉnh trình tự cuối cùng bằng cách xóa một lần phiên bản của \ d \ W * và tạo biểu thức cuối cùng (\ d {1,3})
fezfox

22

Bạn có thể sử dụng libphonenumber thư viện từ 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
Nó có thể là một giải pháp tốt nhưng chỉ để kiểm tra số điện thoại, trước khi sử dụng thư viện này, bạn phải nhập một lượng lớn js ... vì libphonenumber.js cần thư viện đóng ... nó không phải là một giải pháp nhẹ nhàng: /
J. BizMai 19/09/17

11

Điều này sẽ hoạt động đối với các số quốc tế;

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

Tôi sử dụng cái này:

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

Ưu điểm: nhận ra đầu + hoặc 011, cho phép nó dài nếu cần và xử lý nhiều quy ước mở rộng. (#, x, ext, phần mở rộng)


Cái này khá gần với hầu hết các định dạng số điện thoại quốc tế.
feeela

9

Đây là phiên bản "được tối ưu hóa" của regex của bạn:

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

Bạn có thể thay thế \ds bằng [0-9]nếu cú ​​pháp regex của bạn không hỗ trợ \d.



6

Biểu thức chính quy của @ Eric đã sửa đổi - đã thêm danh sách tất cả các mã quốc gia (lấy chúng từ xxxdepy @ Github . Tôi hy vọng bạn sẽ thấy nó hữu ích:

/(\+|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}$/

Hoạt động như một sự quyến rũ. Đối với cả số điện thoại của Hà Lan. Cảm ơn!
mauvm

2

Rõ ràng là có vô số cách để làm điều này, bằng chứng là tất cả các câu trả lời khác nhau được đưa ra cho đến nay, nhưng tôi sẽ ném giá trị 0,02 đô la của mình vào đây và cung cấp regex bên dưới, ngắn gọn hơn một chút so với gần như tất cả những điều trên , nhưng kỹ lưỡng hơn hầu hết là tốt. Nó cũng có tác dụng phụ tốt là để mã quốc gia bằng $ 1 và số địa phương bằng $ 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

Không có lời chỉ trích nào về những câu trả lời tuyệt vời đó, tôi chỉ muốn trình bày giải pháp đơn giản mà tôi sử dụng cho những người tạo nội dung quản trị của chúng tôi:

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

Buộc bắt đầu bằng một dấu cộng hoặc hai số không và sử dụng ít nhất một số nhỏ, khoảng trắng, dấu ngoặc nhọn, dấu trừ và điểm là tùy chọn và không có ký tự nào khác. Bạn có thể xóa tất cả các số không phải số một cách an toàn và sử dụng điều này trong đầu vào tel:. Các con số sẽ có một hình thức biểu diễn chung và tôi không phải lo lắng về việc bị hạn chế.


1

Một phiên bản đơn giản cho các số châu Âu, khớp với các số như 0034617393211 nhưng cũng khớp với các số dài như 004401484172842.

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

Hy vọng nó giúp :·)


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
Mặc dù đoạn mã này có thể trả lời câu hỏi, nhưng nó không cung cấp bất kỳ ngữ cảnh nào để giải thích cách thức hoặc lý do. Cân nhắc thêm một hoặc hai câu để giải thích câu trả lời của bạn.
brandonscript

1

Đây là biểu đồ cho các trường hợp số điện thoại phổ biến nhất sau đây. Mặc dù điều này được điều chỉnh từ quan điểm của Hoa Kỳ cho mã vùng, nó hoạt động cho các kịch bản quốc tế.

  1. Số thực chỉ nên có 10 chữ số.
  2. Đối với các số Hoa Kỳ, mã vùng có thể được bao quanh bằng dấu ngoặc đơn ().
  3. Mã quốc gia có thể dài từ 1 đến 3 chữ số. Tùy chọn có thể được đặt trước dấu +.
  4. Có thể có dấu gạch ngang, dấu cách, dấu chấm hoặc không có dấu cách giữa mã quốc gia, mã vùng và phần còn lại của số.
  5. Số điện thoại hợp lệ không thể là tất cả các số không.

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

Giải trình:

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

Các ví dụ và giải thích khác - https://regex101.com/r/hTH8Ct/2/


1

Tôi đã sử dụng cái này bên dưới:

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

Định dạng + CCC.NNNNNNNNNNxEEEE hoặc 00CCC.NNNNNNNNNNxEEEE

Số điện thoại phải bắt đầu bằng '+' hoặc '00' cho cuộc gọi quốc tế. trong đó C là mã quốc gia có 1–3 chữ số,

N có tới 14 chữ số,

và E là phần mở rộng (tùy chọn).

Dấu cộng đứng đầu và dấu chấm theo sau mã quốc gia là bắt buộc. Ký tự “x” theo nghĩa đen chỉ được yêu cầu nếu có phần mở rộng.



0

Kế hoạch đánh số quốc tế dựa trên ITU E.164 kế hoạch đánh số . Tôi đoán đó là điểm bắt đầu cho biểu thức chính quy của bạn.

Tôi sẽ cập nhật điều này nếu tôi gặp phải để tạo một biểu thức chính quy dựa trên việc đánh số ITU E.164.


0

Biểu thức Regex này hoạt động cho các số điện thoại của Ấn Độ, Canada, Châu Âu, New Zealand, Úc, Hoa Kỳ, cùng với mã quốc gia của họ:

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


0

Điều này phù hợp với tôi, mặc dù không có tiền tố 00, 001, 0011, v.v.:

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



0

Tôi đã thực hiện regexp cho các số điện thoại châu Âu và nó cụ thể dựa trên tiền tố quay số so với độ dài của số.

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

Hãy thử điều này, tôi không biết nếu có bất kỳ số điện thoại nào dài hơn 12:

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

1
Điều này khớp với các số có chính xác 12 chữ số bao gồm cả mã quốc gia. Điều đó sai vì nó không tính đến sự thay đổi độ dài trên toàn thế giới. Hơn nữa, độ dài tối đa thực sự là 15 chữ số .
tmt

1
@tmt ^(00|\+){1}\d{12,15}$Sau đó thì sao?
turingtested vào
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.