I'm mencoba untuk menempatkan bersama-sama yang komprehensif regex untuk validasi nomor telepon. Idealnya itu akan menangani format internasional, tetapi harus menangani KITA format, termasuk yang berikut:
I'll menjawab dengan saat ini saya mencoba, tapi aku'm berharap seseorang memiliki sesuatu yang lebih baik dan/atau lebih elegan.
Pilihan yang lebih baik... hanya strip semua non-digit karakter yang di input (kecuali 'x' dan terkemuka '+' tanda-tanda), mengurus karena Inggris kecenderungan untuk menulis angka dalam bentuk non-standar +44 (0) ...
ketika diminta untuk menggunakan awalan internasional (dalam kasus tertentu, anda harus membuang (0)
seluruhnya).
Kemudian, anda berakhir dengan nilai-nilai seperti:
12345678901
12345678901x1234
345678901x1234
12344678901
12345678901
12345678901
12345678901
+4112345678
+441234567890
Kemudian ketika anda menampilkan, memformat isi hati anda. misalnya
1 (234) 567-8901
1 (234) 567-8901 x1234
Ternyata ada's sesuatu dari spec untuk ini, setidaknya untuk Amerika Utara, yang disebut NANP.
Anda perlu menentukan dengan tepat apa yang anda inginkan. Apa hukum pembatas? Spasi, tanda hubung, dan periode? Tidak ada pembatas yang diperbolehkan? Dapat satu campuran pembatas (misalnya, +0.111-222.3333)? Bagaimana ekstensi (misalnya, 111-222-3333 x 44444) akan ditangani? Apa yang khusus tentang angka-angka, seperti 911? Adalah kode area akan menjadi opsional atau diperlukan?
Berikut ini's regex untuk 7 atau 10 digit, dengan ekstensi yang diperbolehkan, pembatas ruang, tanda hubung, atau periode:
^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$
.*
Jika pengguna ingin untuk memberikan nomor teleponnya, kemudian percaya dia bisa melakukannya dengan benar. Jika dia tidak ingin memberikannya kepada anda kemudian memaksa dia untuk memasukkan angka yang benar baik akan mengirim dia ke pesaing's situs atau membuat dia memasukkan sebuah string acak yang sesuai dengan ekspresi reguler. Aku bahkan mungkin akan tergoda untuk mencari nomor tingkat premi telepon seks dan memasukkan yang bukan.
Saya juga akan mempertimbangkan salah satu dari berikut berlaku entri pada situs web:
"123 456 7890 until 6pm, then 098 765 4321"
"123 456 7890 or try my mobile on 098 765 4321"
"ex-directory - mind your own business"
Saya juga sarankan melihat "libphonenumber" Perpustakaan Google. Aku tahu itu tidak regex tapi itu tidak persis apa yang anda inginkan.
Sebagai contoh, ia akan mengakui bahwa:
15555555555
adalah mungkin, tetapi bukan angka yang valid. Ini juga mendukung negara-negara di luar AS.
Menyoroti fungsi:
getNumberType
- mendapat jenis jumlah didasarkan pada jumlah itu sendiri; mampu membedakan Fixed-line, Mobile, Pulsa gratis, Premium Rate, Biaya Bersama, VoIP dan Nomor Pribadi (jika memungkinkan).isNumberMatch
- mendapat tingkat kepercayaan pada apakah dua angka yang sama.getExampleNumber
/getExampleNumberByType
- menyediakan contoh valid angka untuk semua negara/wilayah, dengan pilihan untuk menentukan jenis contoh nomor telepon yang dibutuhkan.isPossibleNumber
- cepat menebak apakah angka adalah mungkin phonenumber dengan hanya menggunakan panjang informasi, jauh lebih cepat dari validasi penuh.isValidNumber
- full validasi nomor telepon untuk wilayah menggunakan panjang dan informasi awalan.AsYouTypeFormatter
- format nomor telepon on-the-fly ketika pengguna memasukkan masing-masing digit.findNumbers
- menemukan angka-angka yang di input teks.PhoneNumberOfflineGeocoder
- menyediakan informasi geografis yang terkait dengan nomor telepon. Masalah terbesar dengan validasi nomor telepon itu adalah budaya yang sangat tergantung.
(408) 974-2042
adalah valid nomor AS(999) 974-2042
adalah tidak valid nomor AS0404 999 999
adalah valid Australia nomor(02) 9999 9999
juga valid Australia nomor(09) 9999 9999
adalah tidak valid Australia nomorEkspresi reguler adalah baik untuk memeriksa format nomor telepon, tapi itu's tidak benar-benar akan dapat memeriksa validitas nomor telepon.
Saya akan menyarankan melewatkan sederhana ekspresi reguler untuk tes nomor telepon anda terhadap, dan menggunakan perpustakaan seperti Google's libphonenumber
(link ke GitHub proyek).
Menggunakan salah satu dari anda yang lebih kompleks contoh, 1-234-567-8901 x1234
, anda mendapatkan berikut data yang keluar dari libphonenumber
(link untuk demo online):
Validation Results
Result from isPossibleNumber() true
Result from isValidNumber() true
Formatting Results:
E164 format +12345678901
Original format (234) 567-8901 ext. 123
National format (234) 567-8901 ext. 123
International format +1 234-567-8901 ext. 123
Out-of-country format from US 1 (234) 567-8901 ext. 123
Out-of-country format from CH 00 1 234-567-8901 ext. 123
Jadi anda tidak hanya belajar jika nomor telepon yang valid (yang itu), tetapi anda juga mendapatkan konsisten nomor telepon format di lokal anda.
Sebagai bonus, libphonenumber
memiliki sejumlah dataset untuk memeriksa keabsahan nomor telepon, serta memeriksa nomor seperti +61299999999
(versi internasional dari (02) 9999 9999
) kembali sebagai nomor yang sah dengan format:
Validation Results
Result from isPossibleNumber() true
Result from isValidNumber() true
Formatting Results
E164 format +61299999999
Original format 61 2 9999 9999
National format (02) 9999 9999
International format +61 2 9999 9999
Out-of-country format from US 011 61 2 9999 9999
Out-of-country format from CH 00 61 2 9999 9999
libphonenumber juga memberikan anda banyak manfaat tambahan, seperti meraih lokasi nomor telepon terdeteksi sebagai makhluk, dan juga mendapatkan informasi zona waktu dari nomor telepon:
PhoneNumberOfflineGeocoder Results
Location Australia
PhoneNumberToTimeZonesMapper Results
Time zone(s) [Australia/Sydney]
Tapi yang tidak valid nomor telepon Australia ((09) 9999 9999
) kembali bahwa itu bukan nomor telepon yang valid.
Validation Results
Result from isPossibleNumber() true
Result from isValidNumber() false
Google's versi memiliki kode untuk Java dan Javascript, tapi orang-orang juga telah menerapkan perpustakaan untuk bahasa-bahasa lain yang menggunakan Google i18n nomor telepon dataset:
Kecuali anda yakin bahwa anda selalu akan menerima angka-angka dari satu lokal, dan mereka akan selalu berada dalam salah satu format, saya akan sangat menyarankan untuk tidak menulis kode anda sendiri untuk ini, dan menggunakan libphonenumber untuk memvalidasi dan menampilkan nomor telepon.
/^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|ekstensi|x)[\-\.\ \\\/]?(\d+))?$/saya
Ini pertandingan:
- (+351) 282 43 50 50
- 90191919908
- 555-8909
- 001 6867684
- 001 6867684x1
- 1 (234) 567-8901
- 1-234-567-8901 x1234
- 1-234-567-8901 ext1234
- 1-234 567.89/01 ext.1234
- 1(234)5678901x1234
- (123)8575973
- (0055)(123)8575973
Pada $n, menghemat:
Anda dapat mengujinya pada https://www.regexpal.com/?fam=99127
Meskipun jawaban untuk menghapus semua spasi yang rapi, itu doesn't benar-benar memecahkan masalah yang's yang ditimbulkan, yang adalah untuk menemukan regex. Ambil, untuk contoh, saya test script bahwa popularitas sebuah halaman web dan ekstrak semua nomor telepon yang menggunakan regex. Karena anda'd perlu regex lagi pula, anda mungkin juga memiliki regex melakukan semua pekerjaan. Saya datang dengan ini:
1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?
Berikut ini's perl script untuk menguji itu. Ketika anda cocok, $1 berisi kode area, $2 dan $3 berisi nomor telepon, dan $5 berisi ekstensi. Saya test script download file dari internet dan mencetak semua nomor telepon di dalamnya.
#!/usr/bin/perl
my $us_phone_regex =
'1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?';
my @tests =
(
"1-234-567-8901",
"1-234-567-8901 x1234",
"1-234-567-8901 ext1234",
"1 (234) 567-8901",
"1.234.567.8901",
"1/234/567/8901",
"12345678901",
"not a phone number"
);
foreach my $num (@tests)
{
if( $num =~ m/$us_phone_regex/ )
{
print "match [$1-$2-$3]\n" if not defined $4;
print "match [$1-$2-$3 $5]\n" if defined $4;
}
else
{
print "no match [$num]\n";
}
}
#
# Extract all phone numbers from an arbitrary file.
#
my $external_filename =
'http://web.textfiles.com/ezines/PHREAKSANDGEEKS/PnG-spring05.txt';
my @external_file = `curl $external_filename`;
foreach my $line (@external_file)
{
if( $line =~ m/$us_phone_regex/ )
{
print "match $1 $2 $3\n";
}
}
Edit:
Anda dapat mengubah \W untuk \s\W?\s* di regex untuk kencangkan sedikit. Aku't berpikir tentang regex dalam hal, mengatakan, memvalidasi input pengguna pada form ketika saya menulis ini, tapi perubahan ini membuatnya mungkin untuk menggunakan regex untuk tujuan itu.
'1?\s*\W?\s*([2-9][0-8][0-9])\s*\W?\s*([2-9][0-9]{2})\s*\W?\s*([0-9]{4})(\se?x?t?(\d*))?';
Saya menjawab pertanyaan ini pada yang lain JADI pertanyaan sebelum memutuskan untuk juga mencakup jawaban saya sebagai jawaban pada thread ini, karena tidak ada yang menangani bagaimana untuk memerlukan/tidak memerlukan barang-barang, hanya membagi-bagikan regexs: https://stackoverflow.com/questions/25184823/regex-working-wrong-matching-unexpected-things/25298604#25298604
Dari posting saya di situs tersebut, saya've dibuat sebuah panduan cepat untuk membantu orang dengan membuat mereka sendiri regex untuk mereka sendiri yang diinginkan format nomor telepon, yang akan saya peringatan (seperti yang saya lakukan di situs lain) bahwa jika anda terlalu ketat, anda mungkin tidak mendapatkan hasil yang diinginkan, dan tidak ada "satu ukuran cocok untuk semua" solusi untuk menerima semua kemungkinan nomor telepon di dunia - hanya apa yang anda memutuskan untuk menerima sebagai format pilihan. Gunakan dengan resiko anda sendiri.
/^
[\s]
atau s
[(]
dan [)]
. Menggunakan \(
dan \)
jelek dan dapat membuat hal-hal yang membingungkan.?
setelah itu -
atau [-]
. Jika anda tidak menempatkan hal pertama atau terakhir dalam serangkaian karakter lain, meskipun, anda mungkin perlu untuk melarikan diri itu: \-
[-.\s]
akan memerlukan tanda hubung, periode, atau ruang. Tanda tanya setelah terakhir bracket akan membuat semua orang opsional untuk slot. \d{3}
: Membutuhkan 3 digit nomor: 000-999. Singkatan untuk
[0-9][0-9][0-9]
. [2-9]
: Membutuhkan angka 2-9 untuk slot.(\+|1\s)?
: Menerima "plus" atau 1 dan spasi (karakter pipa, |
, adalah "atau"), dan membuatnya opsional. &Quot;plus" tanda harus melarikan diri.[246]
akan memerlukan 2, 4, atau 6. [77/78]
akan memerlukan 77 atau 78.$/
: Akhir ekspresiPerhatikan bahwa stripping ()
karakter tidak bekerja untuk gaya penulisan INGGRIS angka-angka yang lebih umum: +44 (0) 1234 567890
yang berarti memanggil salah satu nomor internasional:
+441234567890
atau di INGGRIS dial 01234567890
Jika anda hanya ingin memastikan anda don't memiliki random sampah di lapangan (yaitu, dari bentuk spammer) ini regex harus dilakukan dengan baik:
^[0-9+\(\)#\.\s\/ext-]+$
Perhatikan bahwa itu doesn't memiliki aturan khusus untuk berapa banyak angka, atau nomor apa yang berlaku pada mereka digit, itu hanya memverifikasi bahwa hanya angka, tanda kurung, tanda hubung, plus, ruang, pon, asterisk, titik, koma, atau huruf e
, x
, t
yang hadir.
Itu harus kompatibel dengan nomor internasional dan lokalisasi format. Apakah anda melihat ada kebutuhan untuk memungkinkan square, keriting, atau kurung siku untuk beberapa daerah? (saat ini mereka tidak't termasuk).
Jika anda ingin mempertahankan per digit aturan (seperti di AS Daerah dan Kode Prefiks (kode tukar) harus jatuh di kisaran 200-999) yah, good luck untuk anda. Mempertahankan kompleks aturan-set yang bisa saja menjadi kadaluwarsa pada setiap titik di masa depan oleh negara manapun di dunia tidak terdengar menyenangkan.
Dan sementara pengupasan semua/sebagian besar karakter non-numerik dapat bekerja dengan baik pada sisi server (terutama jika anda berencana untuk melewati nilai-nilai ini ke dialer), anda mungkin tidak ingin thrash pengguna's masukan selama validasi, terutama jika anda ingin mereka untuk melakukan perbaikan-perbaikan di bidang lain.
Apakah anda telah melihat lebih dari pada RegExLib?
Memasukkan nomor telepon AS dibawa kembali cukup daftar kemungkinan.
Saya mencoba di yang merusak regex:
/^[+#*\(\)\[\]]*([0-9][ ext+-pw#*\(\)\[\]]*){6,45}$/
Menerima:
+(01) 123 (456) 789 ext555
123456
*44 123-456-789 [321]
123456
123456789012345678901234567890123456789012345
*****++[](][((( 123456tteexxttppww
Menolak:
mob 07777 777777
1234 567 890 after 5pm
john smith
(empty)
1234567890123456789012345678901234567890123456
911
Terserah kepada anda untuk membersihkan itu untuk ditampilkan. Setelah memvalidasi itu could menjadi nomor satu sekalipun.
Saya menemukan ini bekerja cukup baik:
^\(*\+*[1-9]{0,3}\)*-*[1-9]{0,3}[-. /]*\(*[2-9]\d{2}\)*[-. /]*\d{3}[-. /]*\d{4} *e*x*t*\.* *\d{0,4}$
Ia bekerja untuk ini nomor format:
1-234-567-8901
1-234-567-8901 x1234
1-234-567-8901 ext1234
1 (234) 567-8901
1.234.567.8901
1/234/567/8901
12345678901
1-234-567-8901 ext. 1234
(+351) 282 433 5050
Pastikan untuk menggunakan global DAN multiline bendera untuk memastikan.
Jika anda're berbicara tentang validasi form, regexp untuk memvalidasi benar makna serta data yang benar akan menjadi sangat kompleks karena berbagai negara dan penyedia standar. Hal itu juga akan sulit untuk tetap up to date.
Saya mengartikan pertanyaannya sebagai mencari luas berlaku pola, yang mungkin tidak akan konsisten secara internal - misalnya memiliki satu set yang valid dari angka-angka, tetapi tidak memvalidasi bahwa batang-line, exchange, dll. untuk yang valid pola untuk awalan kode negara.
Amerika utara lebih mudah, dan untuk internasional, saya lebih memilih untuk menggunakan 'idiomatik' pola yang meliputi cara-cara di mana orang-orang yang menentukan dan ingat nomor:
^((((\(\d{3}\))|(\d{3}-))\d{3}-\d{4})|(\+?\d{2}((-| )\d{1,8}){1,5}))(( x| ext)\d{1,5}){0,1}$
Amerika Utara pola membuat yakin bahwa jika salah satu tanda kurung adalah termasuk keduanya. Internasional menyumbang opsional awal '+' dan kode negara. Setelah itu, anda're dalam idiom. Berlaku pertandingan akan sama:
(xxx)xxx-xxxx
(xxx)-xxx-xxxx
(xxx)xxx-xxxx x123
12 1234 123 1 x1111
12 12 12 12 12
12 1 1234 123456 x12345
+12 1234 1234
+12 12 12 1234
+12 1234 5678
+12 12345678
Ini mungkin bias karena pengalaman saya terbatas ke Amerika Utara, Eropa dan sedikit kecil dari Asia.
Firasat saya ini diperkuat oleh jumlah balasan untuk topik ini - bahwa ada hampir tak terbatas jumlah solusi untuk masalah ini, tidak ada yang akan menjadi elegan.
Jujur, saya akan merekomendasikan anda don't mencoba untuk memvalidasi nomor telepon. Bahkan jika anda bisa menulis toket besar, orang validator yang akan memungkinkan semua sah format, itu akan berakhir sehingga apa pun cukup banyak bahkan dari jarak jauh menyerupai sebuah nomor telepon di tempat pertama.
Menurut saya, solusi yang paling elegan adalah untuk memvalidasi panjang minimum, tidak lebih.
Ini adalah sederhana Regular Expression pola untuk Filipina Nomor Ponsel:
((\+[0-9]{2})|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4}
atau
((\+63)|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4}
akan pertandingan ini:
+63.917.123.4567
+63-917-123-4567
+63 917 123 4567
+639171234567
09171234567
Yang pertama akan mencocokkan dua digit kode negara, sedangkan yang kedua akan pertandingan Filipina kode negara secara eksklusif.
Tes di sini: http://refiddle.com/1ox
Berikut ini's indah pola yang paling cocok validasi yang saya butuhkan untuk mencapai. I'm bukan penulis asli, tapi saya pikir itu's layak berbagi karena saya menemukan masalah ini menjadi sangat kompleks dan tanpa ringkas atau banyak berguna menjawab.
Berikut regex akan menangkap banyak digunakan jumlah dan kombinasi karakter dalam berbagai format nomor telepon global:
/^\s*(?:\+?(\d{1,3}))?([-. (]*(\d{3})[-. )]*)?((\d{3})[-. ]*(\d{2,4})(?:[-.x ]*(\d+))?)\s*$/gm
Positif:
+42 555.123.4567
+1-(800)-123-4567
+7 555 1234567
+7(926)1234567
(926) 1234567
+79261234567
926 1234567
9261234567
1234567
123-4567
123-89-01
495 1234567
469 123 45 67
89261234567
8 (926) 1234567
926.123.4567
415-555-1234
650-555-2345
(416)555-3456
202 555 4567
4035555678
1 416 555 9292
Negatif:
926 3 4
8 800 600-APPLE
Original source: http://www.regexr.com/38pvb
Anda'll memiliki waktu yang sulit berurusan dengan nomor internasional dengan tunggal/sederhana regex, lihat post ini pada kesulitan-kesulitan internasional (dan bahkan amerika utara) nomor telepon.
Anda'll ingin mengurai beberapa digit pertama untuk menentukan apa kode negara, maka tindakan yang berbeda berdasarkan negara.
Di luar itu - daftar yang anda berikan tidak termasuk lain yang umum KITA format - meninggalkan off awal 1. Sebagian besar ponsel di AS don't membutuhkan itu, dan itu'll mulai penyekat generasi muda kecuali mereka'telah dipanggil secara internasional.
Anda've diidentifikasi dengan benar bahwa itu's masalah rumit...
-Adam
Berikut ini's saya mencoba yang terbaik sejauh ini. Ini menangani format di atas, namun saya'm yakin aku'm hilang beberapa lainnya mungkin format.
^\d?(?:(?:[\+]?(?:[\d]{1,3}(?:[ ]+|[\-.])))?[(]?(?:[\d]{3})[\-/)]?(?:[ ]+)?)?(?:[a-zA-Z2-9][a-zA-Z0-9 \-.]{6,})(?:(?:[ ]+|[xX]|(i:ext[\.]?)){1,2}(?:[\d]{1,5}))?$
Setelah membaca jawaban ini, sepertinya tidak ada hal yang't langsung ekspresi reguler yang dapat mengurai melalui sekelompok teks dan mengeluarkan nomor telepon dalam format apapun (termasuk internasional dengan dan tanpa tanda plus).
Berikut ini's apa yang saya digunakan untuk sebuah proyek klien baru-baru ini, di mana kita harus mengkonversi semua nomor telepon dalam format apapun ke tel: link.
Sejauh ini, it's telah bekerja dengan segala sesuatu yang mereka've dilemparkan pada itu, tapi jika kesalahan datang, aku'll update jawaban ini.
Regex:
/(\+*\d{1,})*([ |\(])*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})/
Fungsi PHP untuk mengganti semua nomor telepon dengan tel: link (dalam kasus ada yang penasaran):
function phoneToTel($number) {
$return = preg_replace('/(\+*\d{1,})*([ |\(])*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})/', '<a href="tel:$1$3$4$5">$1 ($3) $4-$5</a>', $number); // includes international
return $return;
}