Espressione regolare per riformattare un numero di telefono statunitense in Javascript


97

Sto cercando di riformattare (sostituire, non convalidare - ci sono molti riferimenti per la convalida) un numero di telefono da visualizzare in Javascript. Ecco un esempio di alcuni dati:

  • 123 4567890
  • (123) 456-7890
  • (123)456-7890
  • 123 456 7890
  • 123.456.7890
  • (vuoto / nullo)
  • 1234567890

C'è un modo semplice per usare un'espressione regolare per farlo? Sto cercando il modo migliore per farlo. Esiste un modo migliore?

Voglio riformattare il numero come segue: (123) 456-7890


3
E quale di questi è il tuo formato di destinazione?
Fino a Helge

Questo: (123) 456-7890
Matt K

3
Direi che rimuovi tutti i caratteri non numerici e prendi tre sottostringhe.
Wiseguy

2
@ Wiseguy, per favore, pubblicalo come risposta (con un esempio), poiché è davvero quello che dovrebbe fare OP.
Brian Driscoll

1
È inoltre necessario specificare come ciascuno dei formati accettati si associ al formato di destinazione, il che non è affatto ovvio se l'input è nullo. A meno che tu non sia disposto a utilizzare un condizionale extra per estirpare quel caso.
Jon

Risposte:


240

Supponendo che tu voglia il formato " (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
}

Ecco una versione che consente il +1codice internazionale opzionale :

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
Perfetto; grazie! Tuttavia, sono passato return (!m) ? nulla return (!m) ? ""dopo aver aggiunto questa funzione.
Matt K

2
Una bella lezione su come affrontare un problema. Stavo cercando di pensare a come abbinare tutti i casi possibili: elimini l'irrilevante e vedi se c'è una corrispondenza. Molto bella.
Jkleg

2
Cordiali saluti, questo non funziona per numeri come + 1555-555-5555
Will

'' + phoneNumberStringè lo stesso di phoneNumberString... È già una stringa.
YungGun

@YungGun a meno che qualcuno non chiami la funzione con un numero, ad esempioformatPhoneNumber(8001231234)
maerics

32

Possibile soluzione:

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
Grazie Sean, mi piace la tua breve semplice soluzione in linea.
user752746

1
Grazie per questo! L'ho cambiato in x = x.replace(/[^\d]+/g, '') .replace(/(\d{1})(\d{3})(\d{3})(\d{4})/, '+$1 ($2) $3-$4');per lavorare aggiungendo "+1" davanti al numero di telefono, ad esempio
Greg A

Grazie! questo è solo di cui avevo bisogno
Albert Hidalgo

8

Questa risposta prende in prestito dalla risposta di maeria. Si differenzia principalmente per il fatto che accetta numeri di telefono inseriti parzialmente e formatta le parti che sono state inserite.

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

Funziona durante la digitazione, aggiungendo il formato desiderato dal poster di origine. Dopo 1,5 ore di ricerca, sono felice di aver provato questo!
fungusanthrax

Ho aggiunto parentesi attorno al prefisso se questo aiuta:(${match[1]}${match[2] ? ') ' : ''}${match[2]}${match[3] ? '-' : ''}${match[3]}
Peter Hollingsworth

In realtà il problema è che non puoi tornare indietro sul "-" o sullo spazio da metà stringa. È necessario impedire la riformattazione quando l'utente newstring.length < oldstring.lengthesegue il backspacing (ad esempio OR per tracciare la posizione del cursore e capire quando l'utente è appena tornato indietro su quei delimitatori ad esempioif (cursorPosition === 4 && numericString.length > 3)
Peter Hollingsworth

Nel mio codice React aggiro questo problema memorizzando internamente solo il numero inserito e quindi formattando ciò che viene inserito nel campo. Quindi il backspace rimuove il carattere precedente nel valore effettivo, non il valore visualizzato.
David Baucum

5

Sto usando questa funzione per formattare i numeri degli Stati Uniti.

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

Accetta quasi tutti i modi immaginabili di scrivere un numero di telefono statunitense. Il risultato è formattato in un formato standard di (987) 654-3210 x123


3

pensare al contrario

Prendi solo le ultime cifre (fino a 10) ignorando il primo "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}`
}

esempio di input / output durante la digitazione

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

Eccone uno che accetterà sia numeri di telefono che numeri di telefono con interni.

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

È possibile utilizzare queste funzioni per verificare i numeri di telefono validi e normalizzarli:

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

Ho esteso la risposta di David Baucum per includere il supporto per estensioni fino a 4 cifre. Include anche le parentesi richieste nella domanda originale. Questa formattazione funzionerà durante la digitazione nel campo.

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

Quasi tutti hanno problemi quando l'utente cerca di tornare indietro sui delimitatori, in particolare dal centro della stringa.

Ecco una soluzione jquery che lo gestisce e si assicura anche che il cursore rimanga nel posto giusto durante la modifica:

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

Le soluzioni di cui sopra sono superiori, soprattutto se si utilizza Java e si riscontrano più numeri con più di 10 cifre come il prefisso del codice internazionale o numeri di interni aggiuntivi. Questa soluzione è di base (sono un principiante nel mondo delle espressioni regolari) e progettata pensando ai numeri di telefono degli Stati Uniti ed è utile solo per stringhe con solo 10 numeri con forse alcuni caratteri di formattazione o forse nessun carattere di formattazione (solo 10 numeri ). Pertanto, consiglierei questa soluzione solo per applicazioni semiautomatiche. Personalmente preferisco memorizzare i numeri come soli 10 numeri senza caratteri di formattazione, ma voglio anche essere in grado di convertire o pulire i numeri di telefono nel formato standard che le persone normali e le app / i telefoni riconosceranno immediatamente a piacimento.

Mi sono imbattuto in questo post alla ricerca di qualcosa che potessi usare con un'app per la pulizia del testo che abbia funzionalità PCRE Regex (ma senza funzioni Java). Pubblicherò questo qui per le persone che potrebbero utilizzare una semplice soluzione Regex pura che potrebbe funzionare in una varietà di editor di testo, pulitori, espansori o anche alcuni gestori di appunti. Io personalmente uso Sublime e TextSoap. Questa soluzione è stata creata per Text Soap poiché si trova nella barra dei menu e fornisce un menu a discesa in cui è possibile attivare azioni di manipolazione del testo su ciò che è selezionato dal cursore o su ciò che è negli appunti.

Il mio approccio consiste essenzialmente in due sostituzioni / ricerca e sostituzione di regex. Ogni ricerca e sostituzione di sostituzione coinvolge due espressioni regolari, una per la ricerca e una per la sostituzione.

Sostituzione / Cerca e sostituisci # 1

  • La prima sostituzione / ricerca e sostituzione elimina i numeri non numerici da un numero altrimenti di 10 cifre a una stringa di 10 cifre.

Prima sostituzione / ricerca Regex:\D

  • Questa stringa di ricerca corrisponde a tutti i caratteri che non sono una cifra.

Prima sostituzione / sostituzione dell'espressione regolare: "" (niente, nemmeno uno spazio)

  • Lascia il campo sostitutivo completamente vuoto, non dovrebbero esistere spazi bianchi inclusi gli spazi. Ciò comporterà l'eliminazione di tutti i caratteri non numerici corrispondenti. Prima di questa operazione avresti dovuto inserire 10 cifre + caratteri di formattazione e uscire con 10 cifre senza caratteri di formattazione.

Sostituzione / Cerca e sostituisci # 2

  • La seconda sostituzione / Ricerca e sostituzione di ricerca nell'ambito dell'operazione Cattura gruppi per prefisso$1 , un gruppo di cattura per la seconda serie di tre numeri $2, e l'ultimo gruppo di cattura per l'ultima serie di quattro numeri $3. L'espressione regolare per la parte sostitutiva dell'operazione inserisce la formattazione del numero di telefono degli Stati Uniti tra il gruppo di cifre acquisito.

Seconda sostituzione / ricerca Regex:(\d{3})(\d{3})(\d{4})

Seconda sostituzione / sostituzione dell'espressione regolare:\($1\) $2\-$3

  • Il backslash \sfugge i caratteri speciali (, ), (<-whitespace), e -dal momento che li stiamo inserendo tra i nostri numeri catturati in gruppi di cattura $1,$2 , e $3per gli Stati Uniti ai fini di formattazione numero di telefono.

  • In TextSoap ho creato un pulitore personalizzato che include le due azioni dell'operazione di sostituzione, quindi in pratica sembra identico all'esecuzione di uno script. Sono sicuro che questa soluzione potrebbe essere migliorata, ma mi aspetto che la complessità aumenti un po '. Una versione migliorata di questa soluzione è accolta come esperienza di apprendimento se qualcuno vuole aggiungere a questo.


-2

Per i numeri di telefono degli Stati Uniti

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

Dividiamo questa espressione regolare in frammenti più piccoli per renderla facile da capire.

  • /^\(?: Significa che il numero di telefono può iniziare con un facoltativo (.
  • (\d{3}): Dopo l'opzionale (devono essere presenti 3 cifre numeriche. Se il numero di telefono non ha un (, deve iniziare con 3 cifre. Ad esempio (308o 308.
  • \)?: Significa che il numero di telefono può avere un optional )dopo le prime 3 cifre.
  • [- ]?: Successivamente il numero di telefono può avere un trattino opzionale ( -) dopo )se presente o dopo le prime 3 cifre.
  • (\d{3}): Quindi devono esserci altre 3 cifre numeriche. Per esempio(308)-135 o 308-135o308135
  • [- ]?: Dopo il secondo gruppo di 3 cifre, il numero di telefono può avere un altro trattino opzionale ( -). Per esempio(308)-135- o 308-135-o308135-
  • (\d{4})$/: Infine, il numero di telefono deve terminare con quattro cifre. Ad esempio (308)-135-7895o308-135-7895 o 308135-7895o 3081357895.

    Riferimento:

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


1
Copiare materiale da altri siti Web e poi non pubblicare nemmeno il collegamento è un comportamento piuttosto brutto: zparacha.com/phone_number_regex
Till Helge

1
Mi dispiace, non avevo idea che dobbiamo postare il link. Ho pensato che dovessimo solo fornire risposte alle domande pubblicate.
Bebu

5
Non va mai bene far sembrare il tuo lavoro qualcun altro. Ricorda per la prossima volta che non c'è niente di sbagliato nel pubblicare i link, ma la copia (specialmente senza fornire un link) non lo è. E hai sempre la possibilità di modificare la tua risposta.
Fino a Helge

Downvoted perché l'autore non ha risposto come sostituire il numero di telefono come richiesto dall'autore.
BrianHVB
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.