Apprendimento delle espressioni regolari [chiuso]


166

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

Risposte:


789

La parte più importante sono i concetti. Una volta capito come funzionano i blocchi predefiniti, le differenze nella sintassi ammontano a poco più dei dialetti lievi. Un livello in cima alla sintassi del tuo motore di espressione regolare è la sintassi del linguaggio di programmazione che stai utilizzando. Lingue come Perl rimuovono la maggior parte di questa complicazione, ma dovrai tenere a mente altre considerazioni se stai usando espressioni regolari in un programma C.

Se pensi alle espressioni regolari come elementi costitutivi che puoi mescolare e abbinare a tuo piacimento, ti aiuta a imparare a scrivere e eseguire il debug dei tuoi schemi ma anche a capire gli schemi scritti da altri.

Inizia semplice

Concettualmente, le espressioni regolari più semplici sono caratteri letterali. Il modello Ncorrisponde al carattere "N".

Le espressioni regolari una accanto all'altra corrispondono alle sequenze. Ad esempio, il modello Nickcorrisponde alla sequenza 'N' seguita da 'i' seguito da 'c' seguito da 'k'.

Se hai mai usato grepUnix, anche se solo per cercare stringhe dall'aspetto ordinario, hai già usato espressioni regolari! (Il rein si grepriferisce alle espressioni regolari.)

Ordina dal menu

Aggiungendo solo un po 'di complessità, puoi abbinare' Nick 'o' nick 'con il modello [Nn]ick. La parte tra parentesi quadre è una classe di caratteri , il che significa che corrisponde esattamente a uno dei caratteri racchiusi. Puoi anche usare gli intervalli nelle classi di caratteri, quindi [a-c]abbina 'a' o 'b' o 'c'.

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

Pensa alle classi di personaggi come a menu: scegline solo una.

Scorciatoie utili

L'uso .può farti risparmiare un sacco di digitazione e ci sono altre scorciatoie per i motivi comuni. Di 'che vuoi abbinare una cifra: un modo per scrivere è [0-9]. Le cifre sono un obiettivo di corrispondenza frequente, quindi puoi invece utilizzare la scorciatoia \d. Altri sono \s(spazi bianchi) e \w(caratteri di parole: alfanumerici o trattino basso).

Le varianti maiuscole sono i loro complementi, quindi si adattano a \Squalsiasi carattere non bianco, ad esempio.

Una volta non è abbastanza

Da lì, puoi ripetere parti del tuo modello con quantificatori . Ad esempio, il modello ab?ccorrisponde a "abc" o "ac" perché il ?quantificatore rende facoltativo il sottotatro che modifica. 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 modello [Nn]*ickcorrisponde a tutti

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

Il primo incontro dimostra un'importante lezione: ci *riesce sempre! Qualsiasi modello può corrispondere a zero volte.

Alcuni altri esempi utili:

  • [0-9]+(e il suo equivalente \d+) corrisponde a qualsiasi numero intero non negativo
  • \d{4}-\d{2}-\d{2} corrisponde alle date formattate come il 01-01-2019

Raggruppamento

Un quantificatore modifica il modello alla sua sinistra immediata. Potresti aspettarti 0abc+0di abbinare '0abc0', '0abcabc0' e così via, ma lo schema immediatamente a sinistra del quantificatore positivo è c. Ciò significa che 0abc+0corrisponde a "0abc0", "0abcc0", "0abccc0" e così via.

Per abbinare una o più sequenze di 'abc' con zeri alle estremità, utilizzare 0(abc)+0. Le parentesi indicano un sottotatro che può essere quantificato come unità. È anche comune per i motori delle espressioni regolari salvare o "acquisire" la parte del testo di input che corrisponde a un gruppo tra parentesi. L'estrazione di bit in questo modo è molto più flessibile e meno soggetta ad errori rispetto al conteggio degli indici e substr.

Alternanza

In precedenza, abbiamo visto un modo per abbinare 'Nick' o 'nick'. Un altro è con alternanza come in Nick|nick. Ricorda che l'alternanza include tutto alla sua sinistra e tutto alla sua destra. Utilizzare il raggruppamento parentesi per limitare il campo di applicazione |, ad esempio , (Nick|nick).

Per un altro esempio, potresti scrivere equivalentemente [a-c]come a|b|c, ma è probabile che non sia ottimale perché molte implementazioni presumono che le alternative abbiano lunghezze superiori a 1.

Escaping

Sebbene alcuni personaggi si abbinino a se stessi, altri hanno significati speciali. Lo schema \d+non corrisponde alla barra rovesciata seguita dalla D minuscola seguita da un segno più: per ottenere ciò, useremmo \\d\+. Una barra rovesciata rimuove il significato speciale dal seguente carattere.

golosità

I quantificatori di espressioni regolari sono avidi. Ciò significa che corrispondono al maggior numero di testo possibile consentendo allo stesso tempo di far corrispondere l'intero modello.

Ad esempio, supponiamo che l'ingresso sia

"Ciao", ha detto, "Come stai?"

Potresti aspettarti ".+"di corrispondere solo a "Ciao" e sarai quindi sorpreso quando vedrai che corrispondeva a "Ciao" fino a "te?".

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

Se il tuo input è '(123) (456)', la prima acquisizione sarà '123'. I quantificatori non avidi vogliono consentire al resto del modello di iniziare la corrispondenza il più presto possibile.

(Quanto alla tua confusione, non conosco nessun dialetto di espressioni regolari dove ((.+?)) farebbe la stessa cosa. Sospetto che qualcosa si sia perso nella trasmissione da qualche parte lungo la strada.)

ancore

Usa il modello speciale ^per abbinare solo all'inizio del tuo input e $per abbinare solo alla fine. Fare "reggilibri" con i tuoi schemi in cui dici "So cosa c'è davanti e dietro, ma dammi tutto tra" è una tecnica utile.

Supponiamo che desideri abbinare i commenti del modulo

-- This is a comment --

tu scriveresti ^--\s+(.+)\s+--$.

Costruisci il tuo

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

Strumenti per la scrittura e il debug di regex:

Libri

Risorse gratuite

Nota

†: l'affermazione sopra che .corrisponde a qualsiasi personaggio è una semplificazione per scopi pedagogici che non è strettamente vera. Il punto corrisponde a qualsiasi personaggio tranne la nuova riga, "\n"ma in pratica raramente ti aspetti uno schema tale da .+attraversare un confine della nuova riga. Le regex del Perl hanno un /sinterruttore e Java Pattern.DOTALL, ad esempio, per far .corrispondere qualsiasi personaggio. Per le lingue che non dispongono di tale funzionalità, è possibile utilizzare qualcosa di simile [\s\S]a "qualsiasi spazio bianco o non spazio bianco", in altre parole.


14
Puoi anche usare il metodo di prova ed errore e seguire il tester e il debugger online regex può essere di grande aiuto: regex101.com
Juraj.Lorinc

2
Vale la pena ricordare che, nonostante sia un modello simile, a{,m}non è una cosa, almeno in Javascript, Perl e Python.
Fondo Monica's Lawsuit

2
Vale la pena ricordare che esistono diversi tipi di motori di espressione regolare con tutti hanno set di funzionalità e regole sintattiche differenti.
Hek2mgl,

1
hackr.io/tutorials/learn-regular-expressions-regex è un ottimo posto per trovare i migliori tutorial di regex online. Tutti i tutorial qui sono inviati e consigliati (votati come SO) dalla comunità di programmazione.
Saurabh Hooda,

2
Apprezzo i tuoi sforzi per portare tutto qui in breve.
Saurabh Tiwari,
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.