Ekspresi Reguler untuk memformat ulang nomor telepon AS dalam Javascript

98

Saya ingin memformat ulang (mengganti, bukan memvalidasi - ada banyak referensi untuk memvalidasi) nomor telepon untuk ditampilkan dalam Javascript. Berikut contoh beberapa datanya:

  • 123 4567890
  • (123) 456-7890
  • (123)456-7890
  • 123 456 7890
  • 123.456.7890
  • (kosong / nol)
  • 1234567890

Apakah ada cara mudah menggunakan ekspresi reguler untuk melakukan ini? Saya mencari cara terbaik untuk melakukan ini. Apakah ada cara yang lebih baik?

Saya ingin memformat ulang nomor tersebut menjadi berikut: (123) 456-7890

Matt K.
sumber
3
Dan yang manakah format target Anda?
Till Helge
Yang ini: (123) 456-7890
Matt K
3
Saya akan mengatakan hanya menghapus semua karakter non-digit lalu mengambil tiga substring.
Wiseguy
2
@Wiseguy tolong posting itu sebagai jawaban (dengan contoh), karena itulah yang harus dilakukan OP.
Brian Driscoll
1
Anda juga perlu menentukan bagaimana masing-masing format yang diterima dipetakan ke format target, yang tidak jelas sama sekali jika inputnya null. Kecuali jika Anda bersedia menggunakan persyaratan tambahan untuk menyingkirkan kasus itu.
Jon

Jawaban:

242

Dengan asumsi Anda menginginkan format " (123) 456-7890":

function formatPhoneNumber(phoneNumberString) {
  var cleaned = ('' + phoneNumberString).replace(/\D/g, '')
  var match = cleaned.match(/^(\d{3})(\d{3})(\d{4})$/)
  if (match) {
    return '(' + match[1] + ') ' + match[2] + '-' + match[3]
  }
  return null
}

Berikut adalah versi yang memungkinkan +1kode internasional opsional :

function formatPhoneNumber(phoneNumberString) {
  var cleaned = ('' + phoneNumberString).replace(/\D/g, '')
  var match = cleaned.match(/^(1|)?(\d{3})(\d{3})(\d{4})$/)
  if (match) {
    var intlCode = (match[1] ? '+1 ' : '')
    return [intlCode, '(', match[2], ') ', match[3], '-', match[4]].join('')
  }
  return null
}
formatPhoneNumber('+12345678900') // => "+1 (234) 567-8900"
formatPhoneNumber('2345678900')   // => "(234) 567-8900"
maerics
sumber
2
Sempurna; Terima kasih! Namun, saya berubah return (!m) ? nullmenjadi return (!m) ? ""setelah menambahkan fungsi ini.
Matt K
2
Pelajaran yang bagus tentang bagaimana mendekati suatu masalah. Saya mencoba memikirkan cara mencocokkan semua kasus yang mungkin - Anda menghilangkan yang tidak relevan dan melihat apakah ada kecocokan. Sangat bagus.
Jkleg
2
FYI ini tidak berfungsi untuk nomor seperti + 1555-555-5555
Akan
'' + phoneNumberStringsama dengan phoneNumberString... Ini sudah menjadi string.
YungGun
@YungGun kecuali seseorang memanggil fungsi dengan nomor, misalnyaformatPhoneNumber(8001231234)
maerics
32

Solusi yang mungkin:

function normalize(phone) {
    //normalize string and remove all unnecessary characters
    phone = phone.replace(/[^\d]/g, "");

    //check if number length equals to 10
    if (phone.length == 10) {
        //reformat and return phone number
        return phone.replace(/(\d{3})(\d{3})(\d{4})/, "($1) $2-$3");
    }

    return null;
}

var phone = '(123)4567890';
phone = normalize(phone); //(123) 456-7890
ioseb
sumber
27

var x = '301.474.4062';
    
x = x.replace(/\D+/g, '')
     .replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');

alert(x);

Sean Bright
sumber
1
Terima kasih Sean, saya suka solusi inline singkat Anda yang sederhana.
pengguna752746
1
Terima kasih untuk ini! Saya mengubahnya x = x.replace(/[^\d]+/g, '') .replace(/(\d{1})(\d{3})(\d{3})(\d{4})/, '+$1 ($2) $3-$4');menjadi berfungsi untuk menambahkan '+1' di depan nomor telepon misalnya
Greg A
Terima kasih! ini hanya yang saya butuhkan
Albert Hidalgo
8

Jawaban ini meminjam dari jawaban maerics. Ini berbeda terutama karena menerima nomor telepon yang dimasukkan sebagian dan memformat bagian-bagian yang telah dimasukkan.

phone = value.replace(/\D/g, '');
const match = phone.match(/^(\d{1,3})(\d{0,3})(\d{0,4})$/);
if (match) {
  phone = `${match[1]}${match[2] ? ' ' : ''}${match[2]}${match[3] ? '-' : ''}${match[3]}`;
}
return phone
David Baucum
sumber
Ini berfungsi saat Anda mengetik, menambahkan format yang diinginkan dari poster sumber. Setelah 1,5 jam mencari, saya senang saya mencoba yang ini!
fungusanthrax
Saya menambahkan tanda kurung di sekitar kode area jika itu membantu:(${match[1]}${match[2] ? ') ' : ''}${match[2]}${match[3] ? '-' : ''}${match[3]}
Peter Hollingsworth
Sebenarnya masalahnya adalah Anda tidak dapat melakukan backspace pada '-' atau spasi dari mid-string. Anda perlu mencegah pemformatan ulang saat pengguna melakukan spasi mundur (misalnya newstring.length < oldstring.lengthATAU untuk melacak posisi kursor dan mencari tahu kapan pengguna baru saja melakukan spasi mundur di atas pembatas tersebut misalnyaif (cursorPosition === 4 && numericString.length > 3)
Peter Hollingsworth
Dalam kode reaksi saya, saya menyiasati ini dengan hanya menyimpan secara internal nomor yang dimasukkan dan kemudian memformat apa yang ditempatkan di lapangan. Jadi backspace menghapus karakter sebelumnya dalam nilai sebenarnya, bukan nilai yang ditampilkan.
David Baucum
5

Saya menggunakan fungsi ini untuk memformat angka AS.

function formatUsPhone(phone) {

    var phoneTest = new RegExp(/^((\+1)|1)? ?\(?(\d{3})\)?[ .-]?(\d{3})[ .-]?(\d{4})( ?(ext\.? ?|x)(\d*))?$/);

    phone = phone.trim();
    var results = phoneTest.exec(phone);
    if (results !== null && results.length > 8) {

        return "(" + results[3] + ") " + results[4] + "-" + results[5] + (typeof results[8] !== "undefined" ? " x" + results[8] : "");

    }
    else {
         return phone;
    }
}

Ia menerima hampir semua cara yang bisa dibayangkan untuk menulis nomor telepon AS. Hasilnya diformat ke dalam bentuk standar (987) 654-3210 x123

mikryz
sumber
3

berpikir mundur

Ambil hanya digit terakhir (hingga 10) dengan mengabaikan "1" pertama.

function formatUSNumber(entry = '') {
  const match = entry
    .replace(/\D+/g, '').replace(/^1/, '')
    .match(/([^\d]*\d[^\d]*){1,10}$/)[0]
  const part1 = match.length > 2 ? `(${match.substring(0,3)})` : match
  const part2 = match.length > 3 ? ` ${match.substring(3, 6)}` : ''
  const part3 = match.length > 6 ? `-${match.substring(6, 10)}` : ''    
  return `${part1}${part2}${part3}`
}

contoh masukan / keluaran saat Anda mengetik

formatUSNumber('+1333')
// (333)

formatUSNumber('333')
// (333)

formatUSNumber('333444')
// (333) 444

formatUSNumber('3334445555')
// (333) 444-5555
Jason Sebring
sumber
1
var numbers = "(123) 456-7890".replace(/[^\d]/g, ""); //This strips all characters that aren't digits
if (numbers.length != 10) //wrong format
    //handle error
var phone = "(" + numbers.substr(0, 3) + ") " + numbers.substr(3, 3) + "-" + numbers.substr(6); //Create format with substrings
Alex Turpin
sumber
1

Hampir semua ini memiliki masalah ketika pengguna mencoba untuk mundur melalui pembatas, terutama dari tengah string.

Berikut solusi jquery yang menangani itu, dan juga memastikan kursor tetap di tempat yang tepat saat Anda mengedit:

//format text input as phone number (nnn) nnn-nnnn
$('.myPhoneField').on('input', function (e){
    var $phoneField = e.target;
    var cursorPosition = $phoneField.selectionStart;
    var numericString = $phoneField.value.replace(/\D/g, '').substring(0, 10);

    // let user backspace over the '-'
    if (cursorPosition === 9 && numericString.length > 6) return;

    // let user backspace over the ') '
    if (cursorPosition === 5 && numericString.length > 3) return;
    if (cursorPosition === 4 && numericString.length > 3) return;

    var match = numericString.match(/^(\d{1,3})(\d{0,3})(\d{0,4})$/);
    if (match) {
        var newVal = '(' + match[1];
        newVal += match[2] ? ') ' + match[2] : '';
        newVal += match[3] ? '-' + match[3] : '';

        // to help us put the cursor back in the right place
        var delta = newVal.length - Math.min($phoneField.value.length, 14);      
        $phoneField.value = newVal;
        $phoneField.selectionEnd = cursorPosition + delta;
    } else {
        $phoneField.value = '';        
    }
})
Peter Hollingsworth
sumber
0

Ini salah satu yang akan menerima nomor telepon dan nomor telepon dengan ekstensi.

function phoneNumber(tel) {
var toString = String(tel),
    phoneNumber = toString.replace(/[^0-9]/g, ""),
    countArrayStr = phoneNumber.split(""),
    numberVar = countArrayStr.length,
    closeStr = countArrayStr.join("");
if (numberVar == 10) {
    var phone = closeStr.replace(/(\d{3})(\d{3})(\d{4})/, "$1.$2.$3"); // Change number symbols here for numbers 10 digits in length. Just change the periods to what ever is needed.
} else if (numberVar > 10) {
    var howMany = closeStr.length,
        subtract = (10 - howMany),
        phoneBeginning = closeStr.slice(0, subtract),
        phoneExtention = closeStr.slice(subtract),
        disX = "x", // Change the extension symbol here
        phoneBeginningReplace = phoneBeginning.replace(/(\d{3})(\d{3})(\d{4})/, "$1.$2.$3"), // Change number symbols here for numbers greater than 10 digits in length. Just change the periods and to what ever is needed. 
        array = [phoneBeginningReplace, disX, phoneExtention],
        afterarray = array.splice(1, 0, " "),
        phone = array.join("");

} else {
    var phone = "invalid number US number";
}
return phone;
}

phoneNumber("1234567891"); // Your phone number here
jjones
sumber
0

Anda dapat menggunakan fungsi ini untuk memeriksa nomor telepon yang valid dan menormalkannya:

let formatPhone = (dirtyNumber) => {
 return dirtyNumber.replace(/\D+/g, '').replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');
}

let isPhone = (phone) => {
   //normalize string and remove all unnecessary characters
   phone = phone.replace(/\D+/g, '');
   return phone.length == 10? true : false;
}
Rodnier Borrego Clavero
sumber
0

Saya telah memperpanjang jawaban David Baucum untuk menyertakan dukungan untuk ekstensi hingga 4 digit. Ini juga mencakup tanda kurung yang diminta dalam pertanyaan asli. Pemformatan ini akan berfungsi saat Anda mengetik di bidang.

phone = phone.replace(/\D/g, '');
const match = phone.match(/^(\d{1,3})(\d{0,3})(\d{0,4})(\d{0,4})$/);
if (match) {
    phone = `(${match[1]}${match[2] ? ') ' : ''}${match[2]}${match[3] ? '-' : ''}${match[3]}${match[4] ? ' x' : ''}${match[4]}`;
}
return phone;
Jeremy
sumber
0

Solusi di atas lebih unggul, terutama jika menggunakan Java, dan menemukan lebih banyak nomor dengan lebih dari 10 digit seperti awalan kode internasional atau nomor ekstensi tambahan. Solusi ini dasar (saya seorang pemula di dunia regex) dan dirancang dengan nomor Telepon AS dan hanya berguna untuk string dengan hanya 10 angka dengan mungkin beberapa karakter pemformatan, atau mungkin tanpa karakter pemformatan sama sekali (hanya 10 angka ). Karena itu, saya akan merekomendasikan solusi ini hanya untuk aplikasi semi-otomatis. Secara pribadi saya lebih suka menyimpan nomor hanya sebagai 10 angka tanpa memformat karakter, tetapi juga ingin dapat mengubah atau membersihkan nomor telepon ke format standar orang normal dan aplikasi / telepon akan langsung mengenali sesuka hati.

Saya menemukan posting ini mencari sesuatu yang dapat saya gunakan dengan aplikasi pembersih teks yang memiliki kemampuan PCRE Regex (tetapi tidak ada fungsi java). Saya akan memposting ini di sini untuk orang-orang yang dapat menggunakan solusi Regex murni sederhana yang dapat bekerja di berbagai editor teks, pembersih, ekspander, atau bahkan beberapa manajer papan klip. Saya pribadi menggunakan Sublime dan TextSoap. Solusi ini dibuat untuk Text Soap karena ada di bilah menu dan menyediakan menu drop-down di mana Anda dapat memicu tindakan manipulasi teks pada apa yang dipilih oleh kursor atau apa yang ada di clipboard.

Pendekatan saya pada dasarnya adalah dua substitusi / cari dan ganti regex. Setiap pencarian dan penggantian substitusi melibatkan dua ekspresi reguler, satu untuk pencarian dan satu untuk mengganti.

Pergantian / Pencarian & Ganti # 1

  • Substitusi pertama / cari & ganti strip nomor non-numerik dari angka 10-digit sebaliknya ke string 10-digit.

Pergantian Pertama / Pencarian Regex:\D

  • String pencarian ini cocok dengan semua karakter yang bukan digit.

Substitusi Pertama / Ganti Ekspresi Reguler: "" (tidak ada, bahkan spasi)

  • Biarkan bidang pengganti benar-benar kosong, tidak boleh ada spasi kosong termasuk spasi. Ini akan mengakibatkan semua karakter non-digit yang cocok dihapus. Anda seharusnya sudah masuk dengan 10 digit + karakter pemformatan sebelum operasi ini dan keluar dengan 10 digit tanpa karakter pemformatan.

Pergantian / Pencarian & Ganti # 2

  • Substitusi kedua / cari dan ganti bagian pencarian dari operasi menangkap grup untuk kode area $1, grup tangkapan untuk set kedua dari tiga angka $2, dan grup tangkapan terakhir untuk set terakhir dari empat angka $3. Ekspresi reguler untuk bagian pengganti operasi memasukkan format nomor telepon AS di antara kelompok digit yang diambil.

Pergantian Kedua / Pencarian Regex:(\d{3})(\d{3})(\d{4})

Substitusi Kedua / Replace Regex:\($1\) $2\-$3

  • Backslash \lolos karakter khusus (, ), (<-whitespace), dan -karena kita memasukkan mereka antara nomor kami ditangkap di kelompok capture $1, $2, & $3untuk tujuan nomor telepon format AS.

  • Di TextSoap saya membuat pembersih khusus yang menyertakan dua tindakan operasi substitusi, jadi dalam praktiknya ini terasa identik dengan menjalankan skrip. Saya yakin solusi ini dapat ditingkatkan tetapi saya mengharapkan kerumitan meningkat sedikit. Versi perbaikan dari solusi ini disambut sebagai pengalaman belajar jika ada yang ingin menambahkannya.

adamlogan
sumber
-2

Untuk Nomor Telepon AS

/^\(?(\d{3})\)?[- ]?(\d{3})[- ]?(\d{4})$/

Mari bagi ekspresi reguler ini menjadi fragmen yang lebih kecil agar mudah dipahami.

  • /^\(?: Berarti nomor telepon dapat dimulai dengan opsional (.
  • (\d{3}): Setelah opsional (harus ada 3 digit angka. Jika nomor telepon tidak memiliki (, harus dimulai dengan 3 digit. Misalnya (308atau 308.
  • \)?: Berarti nomor telepon dapat memiliki pilihan )setelah 3 digit pertama.
  • [- ]?: Selanjutnya nomor telepon dapat memiliki tanda hubung opsional ( -) setelah )jika ada atau setelah 3 digit pertama.
  • (\d{3}): Maka harus ada 3 digit numerik lagi. Misalnya (308)-135atau 308-135atau308135
  • [- ]?: Setelah rangkaian 3 digit kedua, nomor telepon dapat memiliki tanda hubung opsional lainnya ( -). Misalnya (308)-135-atau 308-135-atau308135-
  • (\d{4})$/: Terakhir, nomor telepon harus diakhiri dengan empat digit. Misalnya (308)-135-7895atau 308-135-7895atau 308135-7895atau 3081357895.

    Referensi:

http://www.zparacha.com/phone_number_regex/

Bebu
sumber
1
Menyalin barang dari situs web lain dan bahkan tidak memposting tautannya adalah perilaku yang sangat buruk: zparacha.com/phone_number_regex
Till Helge
1
Saya minta maaf, saya tidak tahu bahwa kami harus memposting tautan. Saya pikir kami hanya harus memberikan jawaban atas pertanyaan yang diposting.
Bebu
5
Hal ini tidak pernah ok untuk membuat yang lain terlihat pekerjaan someones seperti Anda sendiri. Ingatlah untuk lain kali bahwa tidak ada yang salah dengan memposting tautan, tetapi menyalin (terutama tanpa memberikan tautan) tidak. Dan Anda selalu memiliki opsi untuk mengedit jawaban Anda.
Till Helge
Diturunkan karena penulis tidak menjawab bagaimana cara mengganti nomor telepon sesuai permintaan penulis.
BrianHVB