JavaScript Espressioni regolari oltre le basi

Nel nostro precedente tutorial sulle espressioni regolari in JavaScript, hai imparato l'utilità delle espressioni regolari e come scriverne alcune per abbinarle a modelli semplici.

Dopo aver letto il tutorial precedente, ora dovresti avere una buona comprensione di caratteri speciali come una barra rovesciata e sequenze di caratteri come \ w o \ W. Ecco un riassunto molto veloce di quelle sequenze di caratteri:

  1. Puoi usare \ d\ D per abbinare una cifra o un carattere non numerico rispettivamente in una stringa qualsiasi. I caratteri numerici includono 0, 1, 2, 3, 4, 5, 6, 7, 8 e 9. Tutti gli altri caratteri saranno abbinati da \ D.
  2. Puoi usare \ w\ W per abbinare un carattere di parola o non parola in una stringa qualsiasi. I caratteri di Word includono alfabeti, cifre e caratteri di sottolineatura. Tutto il resto, come ₹,%, ecc., È considerato un carattere non di parole.
  3. Puoi usare \S\S per abbinare caratteri spaziali o caratteri non spaziali in una stringa. I caratteri spaziali includono spazio, tabulazione, avanzamento modulo e avanzamento riga.

Invece di abbinare un personaggio alla volta, puoi usare il * simbolo per far corrispondere l'espressione precedente zero o più volte. Il + il carattere corrisponderà similmente all'espressione precedente 1 o più volte.

È possibile abbinare un motivo a un numero specifico di volte aggiungendo n, m ad esso. Qui, n è il numero minimo di volte che vuoi abbinarlo, e m è il limite massimo Se non si specifica un valore per m, l'espressione precedente sarà abbinata più volte possibile.

Dovresti controllare il mio precedente tutorial se qualcosa che abbiamo appena trattato non è chiaro. Ho spiegato tutto in modo più dettagliato lì.

Passiamo ora ad alcune sequenze di caratteri più sofisticate nelle espressioni regolari, in modo da ottenere il meglio da esse e capire come scrivere espressioni che corrispondono a schemi complicati.

Partite non golose con il ? Personaggio

Il ? personaggio significa cose diverse in situazioni diverse.

Se usato da solo, questo carattere corrisponde all'espressione precedente a 0 o 1 volte. In questo senso, è lo stesso di 0,1.

Puoi anche usare ? subito dopo altri quantificatori come *, + e per abbinare il numero minimo possibile di caratteri. In altre parole, trasformerà quei quantificatori avidi in non-avidi. Questo può essere un po 'difficile da capire senza guardare esempi dal vivo, quindi vediamo prima un esempio.

Considera la seguente frase:

Mi è stato assegnato 17321HDGE come id utente mentre il mio amico è stato assegnato a FHES193EK1.

Ora, vediamo tutte le partite che sarebbero state restituite da diversi quantificatori e dalla loro controparte non avida.

Se usiamo l'espressione / \ D + / g nell'esempio, corrisponderà a uno o più caratteri numerici consecutivi. A causa della bandiera globale, ci saranno tre partite: 17321, 193, e 1.

Dovresti notare quello 193 e 1 sono considerati corrispondenze differenti perché sono separati da EK.

L'esempio seguente mostra le partite senza l'uso di alcun quantificatore.

var re = / \ d + / g; var count = 0; var textString = "Mi è stato assegnato 17321HDGE come id utente mentre il mio amico è stato assegnato a FHES193EK1."; var match = re.exec (textString); while (match! == null) console.log (match [0]); match = re.exec (textString); contare ++;  console.log ("Total Matches:" + count); / * Output 17321 193 1 Totale risultati: 3 * /

Ora, aggiungendo a ? personaggio dopo \ d+ restituirà nove diverse corrispondenze. Fondamentalmente, / \ D +? / trasformerà ciascun carattere numerico in una corrispondenza separata. Perché?

È perchè \ d+ per definizione si suppone che corrisponda a una o più cifre. Dal momento che il ? il carattere deve corrispondere al numero minimo possibile di caratteri, corrisponde solo a una cifra alla volta.

Il non-avido ? il quantificatore restituirà 9 piccole corrispondenze a cifra singola questa volta. Per brevità, ho commentato la riga che registra le partite in console.

var re = / \ d +? / g; var count = 0; var textString = "Mi è stato assegnato 17321HDGE come id utente mentre il mio amico è stato assegnato a FHES193EK1."; var match = re.exec (textString); while (match! == null) // console.log (match [0]); match = re.exec (textString); contare ++;  console.log ("Total Matches:" + count); / * Corrispondenze totali di output: 9 * /

Facciamo un altro esempio. L'espressione regolare / \ W + / manterrà i caratteri di parole corrispondenti purché non vengano interrotti da un carattere non di parole come lo spazio. Nel nostro caso, corrisponderà a intere parole separate dallo spazio come assegnato e 17321HDGE una volta.

Se sostituiamo la nostra espressione regolare originale con / \ W + /, otterremo 14 partite diverse. Fondamentalmente, ogni parola sarà la sua corrispondenza. Puoi vedere tu stesso l'output commentando la linea.

var re = / \ w + / g; var count = 0; var textString = "Mi è stato assegnato 17321HDGE come id utente mentre il mio amico è stato assegnato a FHES193EK1."; var match = re.exec (textString); while (match! == null) // console.log (match [0]); match = re.exec (textString); contare ++;  console.log ("Total Matches:" + count); / * Corrispondenze totali di output: 14 * /

Ora, cambiando l'espressione in / \ W +? / restituirà ciascun carattere di parola come una corrispondenza separata e otterrai 68 corrispondenze.

Diamo un'occhiata all'ultimo esempio prima di procedere ulteriormente. L'espressione regolare / \ W 4, / restituirà tutte le parole nella nostra frase di quattro caratteri o più. Quindi corrisponde avere, stato, assegnato, e 17321HDGE, tra gli altri. Ora girando a / \ W 4,? / restituirebbe più corrispondenze di parole con più di quattro caratteri. Nel nostro esempio, le corrispondenze restituite sarebbero avere, stato, assi, gnata, 1732, e 1HGD. Il personaggio E alla fine di 17321HDGE non fa parte di alcuna partitaperché non potrebbe essere nel gruppo di quattro caratteri di parole consecutivi.

var re = / \ w 4, / g; var count = 0; var textString = "Mi è stato assegnato 17321HDGE come id utente mentre il mio amico è stato assegnato a FHES193EK1."; var match = re.exec (textString); while (match! == null) console.log (match [0]); match = re.exec (textString); contare ++;  console.log ("Total Matches:" + count); / * All'uscita è stato assegnato l'utente 17321HDGE mentre l'amico ha assegnato FHES193EK1 Partite totali: 9 * /

Utilizzo delle parentesi con il? Personaggio

Nel mio precedente tutorial sull'espressione regolare, ho trattato brevemente come utilizzare le parentesi per ricordare parte di una corrispondenza. Se usato con a ? carattere, possono servire anche altri scopi.

A volte, vuoi un gruppo di caratteri da abbinare come un'unità. Ad esempio, potresti cercare le occorrenze di n / A una o due volte come una corrispondenza nel seguente testo.

na naa nnaa nana naana

Per chiarimenti, stai cercando il testo in grassetto come corrispondenze: n / A n / Aunn / Aun (Nana) n / Aunn / A. La parte tra parentesi dovrebbe essere abbinata come un'unità, quindi conta come una sola partita.

Quasi tutti quelli che sono appena agli inizi con regex useranno l'espressione / Na 1,2 / con l'intenzione di ottenere il risultato previsto. Nelle loro menti, il 1,2 parte dovrebbe corrispondere a una o due occorrenze di n e un insieme. Tuttavia, corrisponde effettivamente a una singola occorrenza di n seguito da 1 o 2 occorrenze del personaggio un.

Ho reso le corrispondenze restituite da / Na 1,2 / in grassetto per chiarimenti: n / A naa nnaa (NA) (na) (NAA) (na). Le parti tra parentesi sono partite separate. Come puoi vedere, non stiamo ottenendo il risultato che volevamo perché 1,2 non sta considerando n / A essere una singola unità che deve essere abbinata.

La soluzione qui è usare le parentesi per dire a JavaScript di eguagliare n / A come unità. Tuttavia, come abbiamo visto nel tutorial precedente, JavaScript inizierà a ricordare la corrispondenza a causa delle parentesi.

Se non vuoi che JavaScript ricordi la partita, dovrai aggiungere ?: prima del gruppo di caratteri che stai cercando di abbinare. Nel nostro caso, l'espressione finale diventerebbe / (?: na) 1,2 /. Il gruppo n / A sarà abbinato come un'unità ora, e non sarà ricordato. Ho evidenziato le corrispondenze finali restituite con questa espressione in grassetto: n / A n / Aunn / Aa (nana) n / Aunn / A.

Nell'esempio seguente vengono registrate tutte le corrispondenze nella console. Dato che ci sono 6 partite totali, il totale delle partite è 6.

var re = / (?: na) 1,2 / g; var count = 0; var textString = "na naa nnaa nana naana"; var match = re.exec (textString); while (match! == null) console.log (match [0]); match = re.exec (textString); contare ++;  console.log ("Total Matches:" + count); / * Risultato na na na na na na Totale partite: 6 * /

Lookahead e Lookahead Negated

Ci sono molte situazioni in cui cerchiamo di abbinare un determinato set di caratteri, ma solo se sono o non sono seguiti da un altro set di caratteri. Ad esempio, potresti cercare la parola mele in un testo ma vogliono solo quelle partite che sono seguite da siamo. Considera la seguente frase.

le mele sono deliziose Abbiamo mangiato mele tutto il giorno. A tutti quelli che mangiavano mele piacevano loro.

Nell'esempio sopra, vogliamo solo la prima parola come corrispondenza. Ogni altra occorrenza della parola non dovrebbe essere nelle partite.

Un modo per ottenere ciò è usare la seguente espressione regolare un (? = b). La parola che vogliamo abbinare è un, e la parola che dovrebbe venire dopo un è B. Nel nostro caso, l'espressione diventerebbe / mele (? = \ Sare) /. Ricorda che la parola siamo non è incluso in questa partita.

var re = / apples (? = \ sare) / g; var count = 0; var textString = "le mele sono deliziose, abbiamo mangiato mele tutto il giorno e tutti quelli che mangiavano le mele le piacevano"; var match = re.exec (textString); while (match! == null) console.log (match [0]); match = re.exec (textString); contare ++;  console.log ("Total Matches:" + count); / * Miglia di output Totale partite: 1 * /

Questa espressione regolare, in cui guardiamo ciò che viene dopo nella stringa prima di decidere se la parola è una corrispondenza, è chiamata lookahead.

Una situazione molto simile si presenterebbe se decideste di abbinare mele solo se lo fosse non seguito da un set specifico di caratteri. In questi casi, è necessario sostituire ?= con ?! nella tua espressione regolare. Se stessimo cercando tutte le occorrenze di mele quali sono non seguito da siamo, noi useremo / mele (?! \ Sare) / come nostra espressione regolare. Ci saranno due partite di successo per la nostra frase di prova.

var = = mele (?! \ sare) / g; var count = 0; var textString = "le mele sono deliziose, abbiamo mangiato mele tutto il giorno e tutti quelli che mangiavano le mele le piacevano"; var match = re.exec (textString); while (match! == null) console.log (match [0]); match = re.exec (textString); contare ++;  console.log ("Total Matches:" + count); / * Mele di mele in uscita Totale partite: 2 * /

Un'altra cosa: non è necessario utilizzare due espressioni regolari separate per trovare tutte le corrispondenze seguite da una delle due parole specificate. Tutto quello che devi fare è aggiungere l'operatore del tubo tra quelle parole, e sei a posto. Ad esempio, se stai cercando tutte le occorrenze di Apple che sono seguite da siamo o erano, dovresti usare / mele (\ Sare |?! \ swere) / come la tua espressione regolare.

Pensieri finali

In questo tutorial, abbiamo imparato come scrivere espressioni regolari complicate per abbinare i modelli che stiamo cercando. Possiamo usare lo speciale ? carattere per restituire il numero minimo richiesto del carattere precedente come corrispondenza. Allo stesso modo, possiamo usare il ? tra parentesi per assicurarci che il gruppo che stavamo cercando non fosse ricordato. 

Alla fine, abbiamo appreso che il ?= e ?! le sequenze di caratteri in un'espressione regolare ci danno l'opportunità di restituire un determinato set di caratteri come corrispondenza solo se sono o non sono seguiti da un altro set di caratteri specificato.

Se avete domande relative a questo tutorial, sentitevi liberi di farmelo sapere e farò del mio meglio per spiegarle.