Risposte:
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.
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.)
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.
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.
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
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-2019Un 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.
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.
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.
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.)
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+--$.
Le espressioni regolari sono ricorsive, quindi ora che comprendi queste regole di base, puoi combinarle come preferisci.
†: 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.
a{,m}non è una cosa, almeno in Javascript, Perl e Python.