Apprendimento delle espressioni regolari

Non capisco le espressioni regolari. Puoi spiegarmele in un modo facile da seguire? Se ci sono strumenti o libri online, potresti collegarti anche a loro?

La parte più importante sono i concetti. Una volta capito come funzionano i blocchi di costruzione, le differenze nella syntax sono poco più che dialetti miti. Un livello sulla syntax del tuo motore di espressione regolare è la syntax del linguaggio di programmazione che stai utilizzando. Linguaggi come Perl rimuovono la maggior parte di questa complicazione, ma dovrai tenere a mente altre considerazioni se usi espressioni regolari in un programma C.

Se pensi alle espressioni regolari come elementi di base che puoi combinare a tuo piacimento, ti aiuta a imparare come scrivere e fare il debug dei tuoi schemi, ma anche come capire i pattern scritti da altri.

Inizia semplice

Concettualmente, le espressioni regolari più semplici sono caratteri letterali. Il modello N corrisponde al carattere ‘N’.

Le espressioni regolari l’una accanto all’altra corrispondono alle sequenze. Ad esempio, il pattern Nick corrisponde alla sequenza “N” seguita da “i” seguita da “c” seguita da “k”.

Se hai mai usato grep su Unix, anche se solo per cercare stringhe dall’aspetto normale, hai già utilizzato le espressioni regolari! (Il re in grep riferisce alle espressioni regolari).

Ordina dal menu

Aggiungendo solo un po ‘di complessità, puoi abbinare “Nick” o “nick” con lo schema [Nn]ick . La parte tra parentesi quadre è una class di caratteri , il che significa che corrisponde esattamente a uno dei caratteri inclusi. Puoi anche usare gli intervalli nelle classi di caratteri, quindi [ac] corrisponde a ‘a’ o ‘b’ o ‘c’.

Il modello è speciale: anziché corrispondere solo a un punto letterale, corrisponde a qualsiasi carattere . È lo stesso concettualmente della class di personaggi davvero grandi [-.?+%$A-Za-z0-9...] .

Pensa alle classi di caratteri come menu: sceglierne solo uno.

Scorciatoie utili

Utilizzando . puoi risparmiare un sacco di digitazione, e ci sono altre scorciatoie per i modelli comuni. Supponi di voler confrontare gli interi non negativi: un modo di scrivere che è [0-9]+ . Le cifre rappresentano un objective di corrispondenza frequente, quindi potresti utilizzare \d+ per confrontare gli interi non negativi. Gli altri sono \s (spazio bianco) e \w (caratteri parola: caratteri alfanumerici o carattere di sottolineatura).

Le varianti in maiuscolo sono i loro complementi, quindi \S corrisponde ad ogni carattere non- spazio, per esempio.

Una volta non è abbastanza

Da lì, puoi ripetere parti del tuo pattern con quantificatori . Ad esempio, il pattern ab?c corrisponde a ‘abc’ o ‘ac’ perché il ? quantificatore rende il subpattern che modifica facoltativo. Altri quantificatori sono

  • * (zero o più volte)
  • + (una o più volte)
  • {n} (esattamente n volte)
  • {n,} (almeno n volte)
  • {n,m} (almeno n volte ma non più di m volte)

Mettendo insieme alcuni di questi blocchi, il pattern [Nn]*ick corrisponde a tutti

  • ick
  • tacca
  • tacca
  • Nnick
  • nNick
  • nnick
  • (e così via)

La prima partita dimostra una lezione importante: * sempre successo! Qualsiasi modello può corrispondere a zero volte.

Raggruppamento

Un quantificatore modifica il modello alla sua sinistra immediata. Ci si potrebbe aspettare che 0abc+0 corrisponda a ‘0abc0’, ‘0abcabc0’ e così via, ma il modello immediatamente a sinistra del quantificatore più è c . Ciò significa che 0abc+0 corrisponde a ‘0abc0’, ‘0abcc0’, ‘0abccc0’ e così via.

Per abbinare una o più sequenze di ‘abc’ con zeri alle estremità, usare 0(abc)+0 . Le parentesi indicano un subpattern che può essere quantificato come unità. È anche comune per i motori di espressioni regolari salvare o “catturare” la porzione del testo di input che corrisponde a un gruppo tra parentesi. L’estrazione di bit in questo modo è molto più flessibile e meno soggetta a errori rispetto al conteggio di indici e substr .

Alternanza

In precedenza, abbiamo visto un modo per abbinare “Nick” o “nick”. Un altro è con l’alternanza come in Nick|nick . Ricorda che l’alternanza include tutto alla sua sinistra e tutto alla sua destra. Utilizzare le parentesi di raggruppamento per limitare l’ambito di | ad es . (Nick|nick) .

Per un altro esempio, è ansible scrivere in modo equivalente [ac] come a|b|c , ma è probabile che non sia ottimale perché molte implementazioni presuppongono che le alternative avranno una lunghezza maggiore di 1.

Escaping

Sebbene alcuni personaggi si abbinino, altri hanno significati speciali. Il modello \d+ non corrisponde alla barra rovesciata seguita dalla lettera D in minuscolo seguita da un segno più: per ottenere ciò, utilizzere \\d\+ . Un backslash rimuove il significato speciale dal seguente carattere.

golosità

I quantificatori di espressioni regolari sono avidi. Ciò significa che corrispondono più testo ansible e che l’intero pattern può corrispondere correttamente.

Ad esempio, supponiamo che l’input sia

“Ciao”, disse, “Come stai?”

Potresti aspettarti che ".+" Corrisponda solo a “Ciao”, e quindi rimarrai sorpreso quando vedrai che corrisponde a “Ciao” fino a “te?”.

Per passare dall’avida a ciò che potresti pensare cauto, aggiungi un extra ? al quantificatore. Ora capisci come \((.+?)\) , L’esempio della tua domanda funziona. Corrisponde alla sequenza di una parentesi sinistra letterale, seguita da uno o più caratteri e terminata da una parentesi di destra.

Se l’input è ‘(123) (456)’, la prima cattura sarà ‘123’. Quantificatori non grezzi vogliono consentire al resto del pattern di iniziare la corrispondenza il prima ansible.

(Per quanto riguarda la tua confusione, non conosco alcun dialetto di espressioni regolari in cui ((.+?)) Farebbe la stessa cosa. Sospetto che qualcosa si sia perso nella trasmissione da qualche parte lungo la strada.)

ancore

Usa lo speciale pattern ^ per farlo corrispondere solo all’inizio del tuo input e $ per abbinarlo solo alla fine. Fare “fermalibri” con i tuoi schemi in cui dici “so cosa c’è davanti e dietro, ma dammi tutto tra” è una tecnica utile.

Supponi di voler abbinare i commenti del modulo

-- This is a comment --

dovresti scrivere ^--\s+(.+)\s+--$ .

Costruisci il tuo

Le espressioni regolari sono ricorsive, quindi ora che hai compreso queste regole di base, puoi combinarle come preferisci.

Strumenti per scrivere e debugging regex:

  • RegExr (per JavaScript)
  • Perl: YAPE: Regex Explain
  • Regex Coach (motore supportato da CL-PPCRE )
  • RegexPal (per JavaScript)
  • Tester online di espressioni regolari
  • Regex Buddy
  • Regex 101 (per PCRE, JavaScript, Python, Golang)
  • Visual RegExp
  • Expresso (per .NET)
  • Rubulare (per Rubino)
  • Libreria di espressioni regolari (Regex predefiniti per scenari comuni)
  • Txt2RE
  • Regex Tester (per JavaScript)
  • Regex Storm (per .NET)
  • Debuggex (visual regex tester e helper)

Libri

  • Mastering Regular Expressions , 2nd Edition e 3rd edition .
  • Cheat Sheet delle espressioni regolari
  • Ricettario Regex
  • Insegna te stesso le espressioni regolari

Risorse gratuite

  • Espressioni regolari – Tutto ciò che dovresti sapere (serie PDF)
  • Riepilogo syntax Regex
  • Come funzionano i regex

Nota

†: la dichiarazione sopra . corrisponde a qualsiasi personaggio è una semplificazione per scopi pedagogici che non è strettamente vero. Dot corrisponde a qualsiasi carattere tranne newline, "\n" , ma in pratica raramente ti aspetti uno schema come .+ Per attraversare un limite di nuova riga. Le Pattern.DOTALL Perl hanno un interruttore /s e Java Pattern.DOTALL , ad esempio, da effettuare . corrisponde a qualsiasi personaggio. Per le lingue che non hanno tale caratteristica, puoi usare qualcosa come [\s\S] per abbinare “qualsiasi spazio bianco o qualsiasi spazio non vuoto”, in altre parole qualsiasi cosa.