Wyrażenie regularne do ponownego formatowania numeru telefonu w USA w JavaScript


102

Chcę przeformatować (zastąpić, a nie zweryfikować - istnieje wiele odniesień do sprawdzania poprawności) numeru telefonu do wyświetlania w JavaScript. Oto przykład niektórych danych:

  • 123 4567890
  • (123) 456-7890
  • (123)456-7890
  • 123 456 7890
  • 123.456.7890
  • (puste / puste)
  • 1234567890

Czy jest do tego łatwy sposób użycia wyrażenia regularnego? Szukam najlepszego sposobu, aby to zrobić. Czy jest lepszy sposób?

Chcę zmienić numer na następujący: (123) 456-7890


3
A który z nich jest Twoim docelowym formatem?
Till Helge

Ten: (123) 456-7890
Matt K

3
Powiedziałbym, że po prostu usuń wszystkie znaki niebędące cyframi, a następnie weź trzy podciągi.
Wiseguy

2
@Wiseguy, napisz to jako odpowiedź (z przykładem), ponieważ tak naprawdę powinien zrobić OP.
Brian Driscoll

1
Musisz również określić, w jaki sposób każdy z akceptowanych formatów jest odwzorowywany na format docelowy, co nie jest wcale oczywiste, jeśli wartość wejściowa ma wartość null. Chyba że chcesz użyć dodatkowego warunku, aby usunąć ten przypadek.
Jon

Odpowiedzi:


249

Zakładając, że chcesz mieć 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
}

Oto wersja, która zezwala na opcjonalny +1kod międzynarodowy:

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
Doskonały; Dziękuję Ci! Jednak po dodaniu tej funkcji zmieniłem return (!m) ? nullna return (!m) ? "".
Matt K

2
Miła lekcja, jak podejść do problemu. Zastanawiałem się, jak dopasować wszystkie możliwe przypadki - eliminujesz nieistotne i sprawdzasz, czy pasuje. Bardzo dobrze.
Jkleg

2
Do Twojej wiadomości, to nie działa w przypadku numerów takich jak + 1555-555-5555
będzie

'' + phoneNumberStringjest taki sam jak phoneNumberString... To już jest ciąg.
YungGun

@YungGun chyba, że ​​ktoś wywoła funkcję numerem, np.formatPhoneNumber(8001231234)
maerics

32

Możliwe rozwiązanie:

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
Dziękuję Sean, podoba mi się twoje krótkie, proste rozwiązanie wbudowane.
user752746

1
Dzięki za to! Zmieniłem to tak, x = x.replace(/[^\d]+/g, '') .replace(/(\d{1})(\d{3})(\d{3})(\d{4})/, '+$1 ($2) $3-$4');aby działał w celu dodania „+1” przed numerem telefonu, na przykład
Greg A

Dzięki! to jest po prostu potrzebne
Albert Hidalgo

8

Ta odpowiedź zapożycza się z odpowiedzi Maerics. Różni się przede wszystkim tym, że akceptuje częściowo wprowadzone numery telefonów i formatuje wprowadzone części.

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

Działa to podczas pisania, dodając żądany format z plakatu źródłowego. Po 1,5 godziny poszukiwań cieszę się, że spróbowałem tego!
fungusanthrax

Dodałem nawiasy wokół numeru kierunkowego, jeśli to pomaga:(${match[1]}${match[2] ? ') ' : ''}${match[2]}${match[3] ? '-' : ''}${match[3]}
Peter Hollingsworth,

Właściwie problem polega na tym, że nie można cofnąć się nad „-” lub spacją ze środka ciągu. Musisz uniemożliwić ponowne formatowanie, gdy użytkownik cofa się (np. newstring.length < oldstring.lengthLUB, aby śledzić pozycję kursora i dowiedzieć się, kiedy użytkownik właśnie przeszedł wstecz przez te separatory, np.if (cursorPosition === 4 && numericString.length > 3)
Peter Hollingsworth

W moim kodzie reakcji omijam ten problem, przechowując wewnętrznie tylko wprowadzoną liczbę, a następnie formatując to, co zostanie umieszczone w polu. Tak więc cofnięcie usuwa poprzedni znak w rzeczywistej wartości, a nie wyświetlaną wartość.
David Baucum

7

Używam tej funkcji do formatowania numerów w USA.

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

Akceptuje prawie wszystkie możliwe sposoby zapisu numeru telefonu w USA. Wynik jest formatowany do standardowej postaci (987) 654-3210 x123


3

myślenie wstecz

Weź tylko ostatnie cyfry (do 10), ignorując pierwszą cyfrę „1”.

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

przykładowe wejście / wyjście podczas pisania

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

formatUSNumber('333')
// (333)

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

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

2

Rozszerzyłem odpowiedź Davida Baucuma o obsługę rozszerzeń o długości do 4 cyfr. Zawiera również nawiasy wymagane w pierwotnym pytaniu. To formatowanie będzie działać podczas pisania w polu.

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;

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

1

Prawie wszystkie z nich mają problemy, gdy użytkownik próbuje cofnąć się nad ogranicznikami, szczególnie ze środka ciągu.

Oto rozwiązanie jQuery, które to obsługuje, a także zapewnia, że ​​kursor pozostaje we właściwym miejscu podczas edycji:

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

Oto taki, który akceptuje zarówno numery telefonów, jak i numery telefonów z numerami wewnętrznymi.

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

Możesz użyć tych funkcji, aby sprawdzić prawidłowe numery telefonów i je znormalizować:

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

Powyższe rozwiązania są lepsze, zwłaszcza w przypadku korzystania z języka Java i napotkania większej liczby numerów z więcej niż 10 cyframi, takich jak międzynarodowy prefiks kodu lub dodatkowe numery wewnętrzne. To rozwiązanie jest podstawowe (jestem początkującym w świecie wyrażeń regularnych) i zostało zaprojektowane z myślą o numerach telefonów w Stanach Zjednoczonych i jest użyteczne tylko w przypadku ciągów zawierających tylko 10 cyfr z pewnymi znakami formatującymi lub bez znaków formatujących (tylko 10 cyfr ). W związku z tym polecałbym to rozwiązanie tylko do aplikacji półautomatycznych. Osobiście wolę przechowywać liczby jako tylko 10 liczb bez formatowania znaków, ale chcę również mieć możliwość konwertowania lub czyszczenia numerów telefonów do standardowego formatu, które normalni ludzie i aplikacje / telefony rozpoznają natychmiast.

Natknąłem się na ten post, szukając czegoś, czego mógłbym użyć z aplikacją do czyszczenia tekstu, która ma możliwości PCRE Regex (ale nie ma funkcji java). Opublikuję to tutaj dla osób, które mogłyby skorzystać z prostego, czystego rozwiązania Regex, które mogłoby działać w różnych edytorach tekstu, programach czyszczących, ekspanderach, a nawet niektórych menedżerach schowka. Osobiście używam Sublime i TextSoap. To rozwiązanie zostało stworzone dla Text Soap, ponieważ znajduje się na pasku menu i zapewnia rozwijane menu, w którym można wywołać akcje manipulacji tekstem na tym, co jest zaznaczone kursorem lub co jest w schowku.

Moje podejście polega zasadniczo na dwóch podstawieniach / wyszukiwaniu i zamianie wyrażeń regularnych. Każde wyszukiwanie i zamiana przez podstawienie obejmuje dwa wyrażenia regularne, jeden do wyszukiwania i jeden do zamiany.

Zastąpienie / Wyszukaj i zamień nr 1

  • Pierwsze podstawienie / wyszukiwanie i zamiana usuwa liczby nienumeryczne z 10-cyfrowej liczby w innym przypadku do 10-cyfrowego ciągu.

Pierwsze podstawienie / wyrażenie regularne wyszukiwania :\D

  • Ten ciąg wyszukiwania obejmuje wszystkie znaki, które nie są cyframi.

Pierwsze podstawienie / zastąpienie wyrażenia regularnego: „” (nic, nawet spacja)

  • Pozostaw pole zastępcze całkowicie puste, nie powinno być żadnych odstępów, w tym spacji. Spowoduje to usunięcie wszystkich pasujących znaków niebędących cyframi. Powinieneś był wprowadzić 10 cyfr + znaki formatujące przed tą operacją i wyjść z 10 cyframi bez znaków formatujących.

Zastąpienie / Wyszukaj i zamień nr 2

  • Drugi podstawienie / wyszukiwania i zamiany wyszukiwarki część grup przechwytuje operację dla numerem kierunkowym $1, grupy przechwytującej na drugi zestaw trzech liczb $2, a ostatnia grupa przechwytywania za ostatni zestaw czterech cyfr $3. Wyrażenie regularne dla części zastępczej operacji wstawia formatowanie numeru telefonu w Stanach Zjednoczonych między przechwyconą grupę cyfr.

Drugie zastąpienie / wyrażenie regularne wyszukiwania :(\d{3})(\d{3})(\d{4})

Drugie zastąpienie / zastąpienie wyrażenia regularnego:\($1\) $2\-$3

  • Odwrotny ukośnik \ucieka znaki specjalne (, ), (<-whitespace), a -ponieważ jesteśmy wkładając je między naszymi przechwyconych numerów w grupach przechwytujących $1, $2, i $3do celów formatowania numer telefonu w USA.

  • W TextSoap stworzyłem niestandardowy środek czyszczący, który zawiera dwie akcje operacji zastępowania, więc w praktyce wygląda to tak samo, jak wykonanie skryptu. Jestem pewien, że to rozwiązanie można by ulepszyć, ale oczekuję, że złożoność znacznie wzrośnie. Ulepszona wersja tego rozwiązania jest mile widziana jako doświadczenie edukacyjne, jeśli ktoś chce coś do tego dodać.


-2

Numery telefonów w USA

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

Podzielmy to wyrażenie regularne na mniejsze fragmenty, aby było łatwe do zrozumienia.

  • /^\(?: Oznacza, że ​​numer telefonu może zaczynać się opcjonalnym (.
  • (\d{3}): Po opcji (muszą znajdować się 3 cyfry. Jeśli numer telefonu nie ma litery (, musi zaczynać się od 3 cyfr. Np . (308Lub 308.
  • \)?: Oznacza, że ​​numer telefonu może mieć wartość opcjonalną )po pierwszych 3 cyfrach.
  • [- ]?: Następnie numer telefonu może mieć opcjonalny łącznik ( -) po ( )jeśli występuje) lub po pierwszych 3 cyfrach.
  • (\d{3}): Następnie muszą być jeszcze 3 cyfry. Np. (308)-135Lub 308-135lub308135
  • [- ]?: Po drugim zestawie 3 cyfr numer telefonu może mieć kolejny opcjonalny łącznik ( -). Np. (308)-135-Lub 308-135-lub308135-
  • (\d{4})$/: Wreszcie numer telefonu musi kończyć się czterema cyframi. Np. (308)-135-7895Lub 308-135-7895lub 308135-7895lub3081357895 .

    Odniesienie :

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


1
Kopiowanie rzeczy z innych stron internetowych, a następnie nawet nie publikowanie linku jest dość złym zachowaniem: zparacha.com/phone_number_regex
Till Helge

1
Przepraszam, nie miałem pojęcia, że ​​musimy zamieścić link. Pomyślałem, że musimy po prostu udzielić odpowiedzi na przesłane pytania.
Bebu

5
Nigdy nie jest w porządku, aby inna osoba wyglądała jak Twoja. Pamiętaj, że następnym razem nie ma nic złego w umieszczaniu linków, ale kopiowanie (zwłaszcza bez podawania linku) już nie. Zawsze możesz edytować swoją odpowiedź.
Do Helge

Ocena negatywna, ponieważ autor nie odpowiedział, jak zamienić numer telefonu, o co prosił autor.
BrianHVB
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.