Javascript'te bir ABD telefon numarasını yeniden biçimlendirmek için Normal İfade


97

Javascript'te görüntülenecek bir telefon numarasını yeniden biçimlendirmek (değiştirmek, doğrulamak değil - doğrulamak için birçok referans var) arıyorum. İşte bazı verilerin bir örneği:

  • 123 4567890
  • (123) 456-7890
  • (123)456-7890
  • 123 456 7890
  • 123.456.7890
  • (boş / boş)
  • 1234567890

Bunu yapmak için normal bir ifade kullanmanın kolay bir yolu var mı? Bunu yapmanın en iyi yolunu arıyorum. Daha iyi bir yol var mı?

Numarayı aşağıdaki şekilde yeniden biçimlendirmek istiyorum: (123) 456-7890


3
Ve bunlardan hangisi hedef formatınız?
Helge

Bu: (123) 456-7890
Matt K

3
Diyelim ki tüm rakam olmayan karakterleri çıkarın ve ardından üç alt dizeyi alın.
Wiseguy

2
@Wiseguy lütfen bunu bir cevap olarak gönderin (bir örnekle), çünkü OP'nin gerçekten yapması gereken budur.
Brian Driscoll

1
Ayrıca, kabul edilen biçimlerden her birinin hedef biçimle nasıl eşleştiğini de belirtmeniz gerekir; bu, giriş boşsa hiç de açık değildir. Bu davayı ayıklamak için fazladan bir koşul kullanmaya istekli değilseniz.
Jon

Yanıtlar:


240

" (123) 456-7890" Biçimini istediğinizi varsayarsak :

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
}

İşte isteğe bağlı +1uluslararası koda izin veren bir sürüm :

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"

2
Mükemmel; teşekkür ederim! Ancak, ben değiştim return (!m) ? nulliçin return (!m) ? ""bu işlevi ekledikten sonra.
Matt K

2
Bir soruna nasıl yaklaşılacağına dair güzel bir ders. Tüm olası vakaları nasıl eşleştireceğimi düşünmeye çalışıyordum - ilgisiz olanı eleyin ve bir eşleşme olup olmadığına bakın. Çok hoş.
Jkleg

2
Bilginize Bu + 1555-555-5555 gibi numaralar için çalışmıyor
Will

'' + phoneNumberStringşununla aynıdır phoneNumberString... Bu zaten bir dizedir.
YungGun

@YungGun, biri işlevi bir numarayla formatPhoneNumber(8001231234)
aramadıkça

32

Olası çözüm:

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

27

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

alert(x);


1
Teşekkürler Sean, kısa, basit satır içi çözümünü beğendim.
user752746

1
Bunun için teşekkürler! x = x.replace(/[^\d]+/g, '') .replace(/(\d{1})(\d{3})(\d{3})(\d{4})/, '+$1 ($2) $3-$4');Örneğin, telefon numarasının önüne '+1' eklemek için çalışacak şekilde değiştirdim
Greg A

Teşekkürler! bu sadece ihtiyacım olan
Albert Hidalgo

8

Bu cevap, maerics'in cevabından alınmıştır. Öncelikle, kısmen girilen telefon numaralarını kabul etmesi ve girilen bölümleri biçimlendirmesi bakımından farklılık gösterir.

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

Bu, siz yazarken çalışır ve kaynak posterden istediğiniz formatı ekler. 1.5 saat aradıktan sonra bunu denediğim için mutluyum!
fungusanthrax

Yardımcı olacaksa alan kodunun etrafına parantez ekledim:(${match[1]}${match[2] ? ') ' : ''}${match[2]}${match[3] ? '-' : ''}${match[3]}
Peter Hollingsworth

Aslında sorun şu ki, '-' veya dizenin ortasındaki boşluğu geri alamazsınız. Kullanıcı geri boşluk bıraktığında yeniden biçimlendirmeyi önlemeniz gerekir (örneğin newstring.length < oldstring.length, imleç konumunu izlemek ve kullanıcının bu sınırlayıcılar üzerinden ne zaman geriye gittiğini anlamak için VEYA örn.if (cursorPosition === 4 && numericString.length > 3)
Peter Hollingsworth

React kodumda, dahili olarak yalnızca girilen sayıyı depolayarak ve ardından alana yerleştirilenleri biçimlendirerek bu sorunu çözüyorum. Dolayısıyla, geri tuşu görüntülenen değeri değil, gerçek değerdeki önceki karakteri kaldırır.
David Baucum

5

ABD numaralarını biçimlendirmek için bu işlevi kullanıyorum.

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

Bir ABD telefon numarası yazmanın neredeyse akla gelebilecek tüm yollarını kabul eder. Sonuç, standart bir (987) 654-3210 x123 biçiminde biçimlendirilir


3

geriye doğru düşünmek

İlk "1" i yok sayarak yalnızca son rakamları (10'a kadar) alın.

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

yazarken örnek girdi / çıktı

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

formatUSNumber('333')
// (333)

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

formatUSNumber('3334445555')
// (333) 444-5555

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

0

İşte hem telefon numaralarını hem de dahili hatlı telefon numaralarını kabul edecek olanı.

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

0

Bu işlevleri geçerli telefon numaralarını kontrol etmek ve normalleştirmek için kullanabilirsiniz:

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

0

Ben uzattığımızı David Baucum yanıtını uzunluğu 4 basamak uzantıları için destek toplamak dahil etmek. Orijinal soruda istenen parantezleri de içerir. Bu biçimlendirme, alana yazarken çalışacaktır.

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;

0

Kullanıcı sınırlayıcılar üzerinde, özellikle dizenin ortasından geri gitmeye çalıştığında, bunların neredeyse hepsinde sorun yaşanır.

İşte bunu ele alan ve ayrıca siz düzenlerken imlecin doğru yerde kalmasını sağlayan bir jquery çözümü:

//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 = '';        
    }
})

0

Yukarıdaki çözümler, özellikle Java kullanılıyorsa ve uluslararası kod öneki veya ek dahili numaralar gibi 10'dan fazla basamaklı daha fazla sayı ile karşılaşıldığında üstündür. Bu çözüm basittir (normal ifade dünyasında yeni başlayan biriyim) ve ABD Telefon numaraları göz önünde bulundurularak tasarlandı ve yalnızca bazı biçimlendirme karakterleri içeren yalnızca 10 sayı içeren veya belki de hiç biçimlendirme karakteri olmayan (yalnızca 10 sayı ). Bu nedenle, bu çözümü yalnızca yarı otomatik uygulamalar için tavsiye ederim. Ben şahsen numaraları karakterleri biçimlendirmeden sadece 10 numara olarak saklamayı tercih ederim, ancak aynı zamanda telefon numaralarını normal insanların ve uygulamaların / telefonların anında tanıyacağı standart biçime dönüştürmek veya temizlemek istiyorum.

PCRE Regex özelliklerine sahip (ancak java işlevi olmayan) bir metin temizleyici uygulamasıyla kullanabileceğim bir şey arayan bu gönderiye rastladım. Bunu, çeşitli metin düzenleyiciler, temizleyiciler, genişleticiler ve hatta bazı pano yöneticilerinde çalışabilecek basit ve saf bir Regex çözümünü kullanabilecek kişiler için burada yayınlayacağım. Şahsen Sublime ve TextSoap kullanıyorum. Bu çözüm, menü çubuğunda bulunduğu için Metin Sabunu için yapılmıştır ve imleç tarafından seçilen veya panodaki öğeyle ilgili metin işleme eylemlerini tetikleyebileceğiniz bir açılır menü sağlar.

Benim yaklaşımım esasen iki ikame / arama ve normal ifadeleri değiştirmektir. Her ikame arama ve değiştirme, biri arama ve diğeri değiştirme için olmak üzere iki normal ifadeyi içerir.

Değiştirme / Ara ve Değiştir # 1

  • İlk değiştirme / arama ve değiştirme, sayısal olmayan sayıları, aksi takdirde 10 basamaklı bir sayıdan 10 basamaklı bir dizeye kadar çıkarır.

İlk Değiştirme / Arama Normal İfadesi:\D

  • Bu arama dizesi, rakam olmayan tüm karakterlerle eşleşir .

İlk Değiştirme / Regex'i Değiştir : "" (hiçbir şey, boşluk bile yok)

  • Yedek alanı tamamen boş bırakın, boşluklar dahil beyaz boşluk olmamalıdır. Bu, tüm eşleşen rakam olmayan karakterlerin silinmesine neden olacaktır. Bu işlemden önce 10 hane + biçimlendirme karakterleri ile başlamalı ve 10 basamaklı sans biçimlendirme karakterleri ile çıkmalısınız.

Değiştirme / Ara ve Değiştir # 2

  • İşlemin ikinci ikame / arama ve değiştirme arama kısmı, alan kodu için grupları $1, ikinci üç sayı kümesi için bir yakalama grubunu $2ve son dört sayı kümesi için son yakalama grubunu yakalar $3. İşlemin ikame kısmı için normal ifade, yakalanan rakam grubu arasına ABD telefon numarası biçimlendirmesi ekler.

İkinci Değiştirme / Arama Normal İfadesi:(\d{3})(\d{3})(\d{4})

İkinci Değiştirme / Regex'i Değiştir :\($1\) $2\-$3

  • Ters eğik çizgi \özel karakterleri kaçar (, ), (<-whitespace) ve -biz yakalama gruplarında bizim yakalanan numaralar arasına takılarak beri $1, $2& $3ABD telefon numarası biçimlendirme amaçlı.

  • TextSoap'ta iki ikame işlemi eylemini içeren özel bir temizleyici oluşturdum, bu nedenle pratikte bir komut dosyasını çalıştırmakla aynı hissi veriyor. Eminim bu çözüm geliştirilebilir, ancak karmaşıklığın biraz artmasını bekliyorum. Bu çözümün geliştirilmiş bir versiyonu, buna eklemek isteyen biri varsa, bir öğrenme deneyimi olarak memnuniyetle karşılanmaktadır.


-2

ABD Telefon Numaraları için

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

Bu düzenli ifadeyi daha küçük parçalara ayıralım, anlaşılması kolay.

  • /^\(?: Telefon numarasının isteğe bağlı olarak başlayabileceği anlamına gelir (.
  • (\d{3}): Opsiyondan sonra (3 sayısal rakam olmalıdır. Telefon numarasında a yoksa (, 3 rakamla başlamalıdır. Örneğin (308veya 308.
  • \)?: Telefon numarasının )ilk 3 haneden sonra isteğe bağlı olabileceği anlamına gelir .
  • [- ]?: Daha sonra, telefon numarasında, varsa -sonra )veya ilk 3 rakamdan sonra isteğe bağlı bir kısa çizgi ( ) olabilir.
  • (\d{3}): O zaman 3 sayısal basamak daha olmalıdır. Örneğin (308)-135veya 308-135veya308135
  • [- ]?: İkinci 3 basamak kümesinden sonra telefon numarasında isteğe bağlı başka bir kısa çizgi ( -) olabilir. Örneğin (308)-135-veya 308-135-veya308135-
  • (\d{4})$/: Son olarak, telefon numarası dört rakamla bitmelidir. Ör. (308)-135-7895Veya 308-135-7895veya 308135-7895veya3081357895 .

    Referans :

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


1
Diğer web sitelerinden bir şeyler kopyalamak ve hatta bağlantıyı yayınlamamak oldukça kötü bir davranış: zparacha.com/phone_number_regex
Helge

1
Üzgünüm, bağlantı göndermemiz gerektiğine dair hiçbir fikrim yoktu. Sadece gönderilen sorulara cevap vermemiz gerektiğini düşündüm.
Bebu

5
Öyle asla kendi gibi başka bir birilerinin çalışma görünmesi için ok. Bir dahaki sefere bağlantı göndermede yanlış bir şey olmadığını, ancak kopyalamanın (özellikle bağlantı sağlamadan) olmadığını unutmayın. Ve her zaman cevabınızı düzenleme seçeneğiniz vardır.
Helge

Yazarın istediği gibi telefon numarasının nasıl değiştirileceğini yanıtlamadığı için olumsuz oy verildi .
BrianHVB
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.