Nozioni di base sulle espressioni regolari in C++

Regular Expression Basics C

Considera la seguente frase tra virgolette:

'Ecco il mio uomo.'

Questa stringa potrebbe essere all'interno del computer e l'utente potrebbe voler sapere se contiene la parola man. Se ha la parola uomo, allora potrebbe voler cambiare la parola uomo in donna; in modo che la stringa dovrebbe leggere:



'Ecco la mia donna.'

Ci sono molti altri desideri come questi da parte dell'utente del computer; alcuni sono complessi. L'espressione regolare, abbreviata, regex, è l'oggetto della gestione di questi problemi da parte del computer. C++ viene fornito con una libreria chiamata regex. Quindi, un programma C++ per gestire le espressioni regolari dovrebbe iniziare con:



#includere

#includere

usando lo spazio dei nomi std;

Questo articolo spiega Nozioni di base sulle espressioni regolari in C++.



Contenuto dell'articolo

Nozioni di base sulle espressioni regolari

Regex

Una stringa come Ecco il mio uomo. sopra è la sequenza target o la stringa target o semplicemente target. man, che è stato cercato, è l'espressione regolare, o semplicemente, regex.

corrispondenza

Si dice che la corrispondenza si verifica quando si trova la parola o la frase che si sta cercando. Dopo l'abbinamento, può avvenire una sostituzione. Ad esempio, dopo che l'uomo si trova sopra, può essere sostituito dalla donna.

Abbinamento semplice

Il seguente programma mostra come viene abbinata la parola uomo.



#includere

#includere

usando lo spazio dei nomi std;

intprincipale()
{

regex reg('uomo');
Se (regex_search('Ecco il mio uomo.',reg))
costo<< 'accoppiato' <<fine;
altro
costo<< 'non abbinato' <<fine;

Restituzione 0;
}

La funzione regex_search() restituisce true se c'è una corrispondenza e restituisce false se non si verifica alcuna corrispondenza. Qui, la funzione accetta due argomenti: il primo è la stringa di destinazione e il secondo è l'oggetto regex. La regex stessa è 'uomo', tra virgolette. La prima istruzione nella funzione main() forma l'oggetto regex. Regex è un tipo e reg è l'oggetto regex. L'output del programma sopra è 'matched', poiché 'man' è visto nella stringa di destinazione. Se 'man' non fosse stato visto nel target, regex_search() avrebbe restituito false e l'output sarebbe stato 'non abbinato'.

L'output del codice seguente non corrisponde:

regex reg('uomo');
Se (regex_search('Ecco il mio lavoro.',reg))
costo<< 'accoppiato' <<fine;
altro
costo<< 'non abbinato' <<fine;

Non corrisponde perché l'espressione regolare 'man' non è stata trovata nell'intera stringa di destinazione, 'Ecco la mia creazione'.

Modello

L'espressione regolare, man sopra, è molto semplice. Le regex di solito non sono così semplici. Le espressioni regolari hanno metacaratteri. I metacaratteri sono caratteri con significati speciali. Un metacarattere è un personaggio sui personaggi. I metacaratteri C++ regex sono:

^$ .* + ? ( ) [ ] { } |

Un'espressione regolare, con o senza metacaratteri, è uno schema.

Classi di personaggi

Parentesi quadre

Un motivo può contenere caratteri tra parentesi quadre. Con questo, una posizione particolare nella stringa di destinazione corrisponderebbe a uno qualsiasi dei caratteri delle parentesi quadre. Considera i seguenti obiettivi:

'Il gatto è nella stanza.'

'Il pipistrello è nella stanza.'

'Il topo è nella stanza.'

L'espressione regolare, [cbr]at corrisponderebbe a cat nel primo obiettivo. Corrisponderebbe a pipistrello nel secondo obiettivo. Corrisponderebbe a ratto nel terzo obiettivo. Questo perché gatto o pipistrello o ratto iniziano con 'c' o 'b' o 'r'. Il seguente segmento di codice illustra questo:

regex reg('[cbr]at');
Se (regex_search('Il gatto è nella stanza.',reg))
costo<< 'accoppiato' <<fine;
Se (regex_search('Il pipistrello è nella stanza.',reg))
costo<< 'accoppiato' <<fine;
Se (regex_search('Il topo è nella stanza.',reg))
costo<< 'accoppiato' <<fine;

L'uscita è:

abbinato

abbinato

abbinato

Gamma di caratteri

La classe, [cbr] nel modello [cbr], corrisponderebbe a diversi possibili caratteri nel target. Corrisponde a 'c' o 'b' o 'r' nel target. Se il bersaglio non ha nessuna di 'c' o 'b' o 'r', seguiti da at, non ci sarebbe corrispondenza.

Alcune possibilità come 'c' o 'b' o 'r' esistono in un intervallo. L'intervallo di cifre, da 0 a 9, ha 10 possibilità e il modello per questo è [0-9]. La gamma di alfabeti minuscoli, dalla a alla z, ha 26 possibilità, e il modello per questo è [a-z]. La gamma di alfabeti maiuscoli, dalla A alla Z, ha 26 possibilità, e il modello per questo è [A-Z]. – non è ufficialmente un metacarattere, ma tra parentesi quadre indica un intervallo. Quindi, quanto segue produce una corrispondenza:

Se (regex_search('ID6id',regex('[0-9]')))

costo<< 'accoppiato' <<fine;

Nota come la regex è stata costruita come secondo argomento. La corrispondenza si verifica tra la cifra, 6 nell'intervallo, da 0 a 9, e 6 nella destinazione, ID6id. Il codice sopra è equivalente a:

Se (regex_search('ID6id',regex('[0123456789]')))

costo<< 'accoppiato' <<fine;

Il codice seguente produce una corrispondenza:

charP[] = 'ID6iE';

Se (regex_search(P,regex('[a-z]')))

costo<< 'accoppiato' <<fine;

Nota che il primo argomento qui è una variabile stringa e non il letterale stringa. La corrispondenza è tra 'i' in [a-z] e 'i' in ID6iE.

Non dimenticare che un intervallo è una classe. Può essere presente del testo a destra dell'intervallo oa sinistra dell'intervallo nel motivo. Il codice seguente produce una corrispondenza:

Se (regex_search('ID2id è un documento d'identità',regex('ID[0-9]id')))

costo<< 'accoppiato' <<fine;

La corrispondenza è tra ID[0-9]id e ID2id. Il resto della stringa di destinazione, è un ID, non corrisponde in questa situazione.

Come usato nell'oggetto dell'espressione regolare (regex), la parola classe significa in realtà un insieme. Cioè, uno dei personaggi del set deve corrispondere.

Nota: il trattino – è un metacarattere solo tra parentesi quadre, che indica un intervallo. Non è un metacarattere nella regex, al di fuori delle parentesi quadre.

Negazione

Una classe che include un intervallo può essere negata. Cioè, nessuno dei caratteri nell'insieme (classe) dovrebbe corrispondere. Questo è indicato con il metacarattere ^ all'inizio del modello di classe, subito dopo la parentesi quadra di apertura. Quindi, [^0-9] significa far corrispondere il carattere nella posizione appropriata nel target, che non è un carattere nell'intervallo, da 0 a 9 inclusi. Quindi il seguente codice non produrrà una corrispondenza:

Se (regex_search('0123456789101112',regex('[^ 0-9]')))

costo<< 'accoppiato' <<fine;

altro

costo<< 'non abbinato' <<fine;

È possibile trovare una cifra nell'intervallo da 0 a 9 in una qualsiasi delle posizioni della stringa di destinazione, 0123456789101112; quindi non c'è corrispondenza – negazione.

Il codice seguente produce una corrispondenza:

Se (regex_search('ABCDEFGHHIJ',regex('[^ 0-9]')))

costo<< 'accoppiato' <<fine;

Non è stato possibile trovare alcuna cifra nella destinazione, ABCDEFGHIJ,; quindi c'è una corrispondenza.

[a-z] è un intervallo al di fuori di [^a-z]. E così [^a-z] è la negazione di [a-z].

[A-Z] è un intervallo al di fuori di [^A-Z]. E così [^A-Z] è la negazione di [A-Z].

Esistono altre negazioni.

Spazi bianchi corrispondenti

' ' o o o o f è un carattere di spazio bianco. Nel codice seguente, l'espressione regolare, corrisponde a ' ' nel target:

Se (regex_search('Di linea uno.R Della linea due.',regex(' ')))

costo<< 'accoppiato' <<fine;

Corrispondenza con qualsiasi carattere di spazio bianco

Il modello o la classe da abbinare a qualsiasi carattere di spazio vuoto è [ f]. Nel codice seguente, ' ' è abbinato:

Se (regex_search('uno due',regex('[TR F] ')))

costo<< 'accoppiato' <<fine;

Corrispondenza di qualsiasi carattere non di spazi bianchi

Il modello o la classe da abbinare a qualsiasi carattere non di spazio vuoto è [^ f]. Il codice seguente produce una corrispondenza perché non ci sono spazi bianchi nella destinazione:

Se (regex_search('1234abcd',regex('[^TR F] ')))

costo<< 'accoppiato' <<fine;

Il punto (.) nel Pattern

Il punto (.) nel modello corrisponde a qualsiasi carattere compreso se stesso, eccetto , nella destinazione. Viene prodotta una corrispondenza nel codice seguente:

Se (regex_search('1234abcd',regex('.')))

costo<< 'accoppiato' <<fine;

Nessun risultato corrispondente nel codice seguente perché la destinazione è .

Se (regex_search(' ',regex('.')))

costo<< 'accoppiato' <<fine;

altro

costo<< 'non abbinato' <<fine;

Nota: all'interno di una classe di caratteri con parentesi quadre, il punto non ha un significato speciale.

Ripetizioni corrispondenti

Un carattere o un gruppo di caratteri può essere presente più di una volta all'interno della stringa di destinazione. Un modello può corrispondere a questa ripetizione. I metacaratteri, ?, *, + e {} vengono utilizzati per abbinare la ripetizione nella destinazione. Se x è un carattere di interesse nella stringa di destinazione, i metacaratteri hanno i seguenti significati:

X*:significa partita'X' 0o più volte,io.e.,un numero qualsiasi di volte

X+:significa partita'X' 1o più volte,io.e.,almeno una volta

X? :significa partita'X' 0o1 tempo

X{n,}:significa partita'X'almeno n o più volte.Notala virgola.

X{n} :incontro'X'esattamente n volte

X{n,m}:incontro'X'almeno n volte,ma non più di m volte.

Questi metacaratteri sono chiamati quantificatori.

Illustrazioni

*

L'* corrisponde al carattere o al gruppo precedente, zero o più volte. o* corrisponde a 'o' nel cane della stringa di destinazione. Corrisponde anche a oo nel libro e alla ricerca. L'espressione regolare, o* corrisponde a boooo in The animal booooed.. Nota: o* corrisponde a dig, dove 'o' ricorre zero (o più) volte.

+

Il + corrisponde al carattere precedente o al gruppo precedente, 1 o più volte. Contrastalo con zero o più volte per *. Quindi l'espressione regolare, e+ corrisponde a 'e' in eat, dove 'e' si verifica una volta. e+ corrisponde anche a ee in pecore, dove 'e' ricorre più di una volta. Nota: e+ non corrisponderà a dig perché in dig, 'e' non si verifica almeno una volta.

?

Il ? corrisponde al carattere o al gruppo precedente, 0 o 1 volta (e non di più). Quindi, e? corrisponde a dig perché 'e' si verifica in dig, tempo zero. e? corrispondenze impostate perché 'e' si verifica in set, una volta. Nota: e? corrisponde ancora alle pecore; sebbene ci siano due 'e' nelle pecore. C'è una sfumatura qui - vedi dopo.

{n,}

Corrisponde ad almeno n ripetizioni consecutive di un carattere o di un gruppo precedente. Quindi l'espressione regolare, e{2,} corrisponde alle due 'e' nella pecora bersaglio, e alle tre 'e' nella pecora bersaglio. e{2,} non corrisponde a set, perché set ha solo una 'e'.

{n}

Corrisponde esattamente a n ripetizioni consecutive di un carattere o di un gruppo precedente. Quindi l'espressione regolare, e{2} corrisponde alle due 'e' nel bersaglio, pecora. e{2} non corrisponde a set perché set ha solo una 'e'. Bene, e{2} corrisponde a due 'e' nel bersaglio, pecora. C'è una sfumatura qui - vedi dopo.

{n,m}

Corrisponde a diverse ripetizioni consecutive di un carattere o di un gruppo precedente, ovunque da n a m inclusi. Quindi, e{1,3} non corrisponde a nulla in dig, che non ha 'e'. Corrisponde alla 'e' del set, alle due 'e' in pecore, alle tre 'e' nelle pecore e alle tre 'e' nelle pecore. C'è una sfumatura nell'ultima partita – vedi dopo.

Alternanza di corrispondenza

Considera la seguente stringa di destinazione nel computer.

L'azienda dispone di suini di diverse dimensioni.

Il programmatore potrebbe voler sapere se questo obiettivo ha una capra, un coniglio o un maiale. Il codice sarebbe il seguente:

charP[] = 'La fattoria ha maiali di diverse dimensioni.';

Se (regex_search(P,regex('capra|coniglio|maiale')))

costo<< 'accoppiato' <<fine;

altro

costo<< 'non abbinato' <<fine;

Il codice produce una corrispondenza. Notare l'uso del carattere di alternanza, |. Ci possono essere due, tre, quattro e più opzioni. Il C++ cercherà prima di trovare la corrispondenza con la prima alternativa, capra, in ogni posizione del carattere nella stringa di destinazione. Se non riesce con la capra, prova l'alternativa successiva, coniglio. Se non riesce con coniglio, prova l'alternativa successiva, maiale. Se pig fallisce, il C++ passa alla posizione successiva nel target e ricomincia con la prima alternativa.

Nel codice sopra, il maiale è abbinato.

Abbinare l'inizio o la fine

Inizio


Se ^ si trova all'inizio dell'espressione regolare, il testo iniziale della stringa di destinazione può essere abbinato all'espressione regolare. Nel codice seguente, l'inizio della destinazione è abc, che corrisponde:

Se (regex_search('abc e def',regex('^ abc')))

costo<< 'accoppiato' <<fine;

Nessuna corrispondenza avviene nel codice seguente:

Se (regex_search('Sì, ​​abc e def',regex('^ abc')))

costo<< 'accoppiato' <<fine;

altro

costo<< 'non abbinato' <<fine;

Qui, abc non è all'inizio del target.

Nota: il carattere circonflesso, '^', è un metacarattere all'inizio dell'espressione regolare, che corrisponde all'inizio della stringa di destinazione. È ancora un metacarattere all'inizio della classe del personaggio, dove nega la classe.

Fine

Se $ è alla fine dell'espressione regolare, il testo finale della stringa di destinazione può essere abbinato all'espressione regolare. Nel codice seguente, la fine del target è xyz, che corrisponde:

Se (regex_search('uvw e xyz',regex('xyz$')))

costo<< 'accoppiato' <<fine;

Nessuna corrispondenza avviene nel codice seguente:

Se (regex_search('uvw e xyz finale',regex('xyz$')))

costo<< 'accoppiato' <<fine;

altro

costo<< 'non abbinato' <<fine;

Qui, xyz non è alla fine dell'obiettivo.

Raggruppamento

Le parentesi possono essere utilizzate per raggruppare i caratteri in un motivo. Considera la seguente regex:

'un concerto (pianista)'

Il gruppo qui è pianista circondato dai metacaratteri ( e ). In realtà è un sottogruppo, mentre un concerto (pianista) è l'intero gruppo. Considera quanto segue:

'Il (pianista è bravo)'

Qui, il sottogruppo o sottostringa è, il pianista è bravo.

Sottostringhe con parti comuni

Un contabile è una persona che si prende cura dei libri. Immagina una biblioteca con un contabile e una libreria. Si supponga che nel computer sia presente una delle seguenti stringhe di destinazione:

'La biblioteca ha uno scaffale che è ammirato.';

'Ecco il contabile.';

'Il contabile lavora con la libreria.';

Supponiamo che l'interesse del programmatore non sia sapere quale di queste frasi si trova nel computer. Tuttavia, il suo interesse è sapere se la libreria o il contabile è presente in qualunque stringa di destinazione si trovi nel computer. In questo caso, la sua regex può essere:

'scaffale|contabile.'

Usando l'alternanza.

Nota che il libro, che è comune a entrambe le parole, è stato digitato due volte, nelle due parole dello schema. Per evitare di digitare book due volte, la regex sarebbe meglio scritta come:

'libro(scaffale|custode)'

Qui, il gruppo, shelf|keeper Il metacarattere alternativo è stato ancora utilizzato, ma non per due parole lunghe. È stato usato per le due parti finali delle due parole lunghe. C++ tratta un gruppo come un'entità. Quindi, C++ cercherà scaffale o custode che viene immediatamente dopo il libro. L'output del seguente codice è abbinato:

charP[] = 'La biblioteca ha una libreria che è ammirata.';

Se (regex_search(P,regex('libro(scaffale|custode)')))

costo<< 'accoppiato' <<fine;

libreria e non contabile sono stati abbinati.

Le costanti_regex icase e multilinea

icase

La corrispondenza fa distinzione tra maiuscole e minuscole per impostazione predefinita. Tuttavia, può essere reso insensibile alle maiuscole. Per ottenere ciò, utilizzare la costante regex::icase, come nel codice seguente:

Se (regex_search('Feedback',regex('alimentazione',regex::icase)))

costo<< 'accoppiato' <<fine;

L'uscita è abbinata. Quindi il feedback con la 'F' maiuscola è stato abbinato al feed con la 'f' minuscola. regex::icase è stato reso il secondo argomento del costruttore regex(). Senza di ciò, la dichiarazione non produrrebbe una corrispondenza.

multilinea

Considera il seguente codice:

charP[] = 'Linea 1 linea 2 linea 3';

Se (regex_search(P,regex('^. * $')))

costo<< 'accoppiato' <<fine;

altro

costo<< 'non abbinato' <<fine;

L'output non corrisponde. L'espressione regolare, ^.*$, corrisponde alla stringa di destinazione dall'inizio alla fine. .* indica qualsiasi carattere tranne , zero o più volte. Quindi, a causa dei caratteri di nuova riga ( ) nella destinazione, non c'era corrispondenza.

La destinazione è una stringa multilinea. Affinché '.' corrisponda al carattere di nuova riga, deve essere creata la costante regex::multiline, il secondo argomento della costruzione regex(). Il codice seguente lo illustra:

charP[] = 'Linea 1 linea 2 linea 3';

Se (regex_search(P,regex('^. * $',regex::multilinea)))

costo<< 'accoppiato' <<fine;

altro

costo<< 'non abbinato' <<fine;

Abbinamento dell'intera stringa di destinazione

Per abbinare l'intera stringa di destinazione, che non ha il carattere di nuova riga ( ), è possibile utilizzare la funzione regex_match(). Questa funzione è diversa da regex_search(). Il codice seguente lo illustra:

charP[] = 'primo secondo terzo';

Se (regex_match(P,regex('.*secondo.*')))

costo<< 'accoppiato' <<fine;

C'è una partita qui. Tuttavia, tieni presente che l'espressione regolare corrisponde all'intera stringa di destinazione e la stringa di destinazione non ha ' '.

L'oggetto match_results

La funzione regex_search() può accettare un argomento tra il target e l'oggetto regex. Questo argomento è l'oggetto match_results. L'intera stringa abbinata (parte) e le sottostringhe abbinate possono essere conosciute con essa. Questo oggetto è un array speciale con metodi. Il tipo di oggetto match_results è cmatch (per stringhe letterali).

Ottenere corrispondenze

Considera il seguente codice:

charP[] = 'La donna che stavi cercando!';

cmatch m;

Se (regex_search(P,m,regex('w.m.n')))

costo<<m[0] <<fine;

La stringa di destinazione ha la parola donna. L'output è donna', che corrisponde alla regex, w.m.n. All'indice zero, l'array speciale contiene l'unica corrispondenza, che è donna.

Con le opzioni di classe, solo la prima sottostringa trovata nel target viene inviata all'array speciale. Il codice seguente lo illustra:

cmatch m;

Se (regex_search('Il topo, il gatto, il pipistrello!',m,regex('[bcr]at')))

costo<<m[0] <<fine;

costo<<m[1] <<fine;

costo<<m[2] <<fine;

L'output è ratto dall'indice zero. m[1] e m[2] sono vuoti.

Con le alternative, solo la prima sottostringa trovata nel target viene inviata all'array speciale. Il codice seguente lo illustra:

Se (regex_search('Il coniglio, la capra, il maiale!',m,regex('capra|coniglio|maiale')))

costo<<m[0] <<fine;

costo<<m[1] <<fine;

costo<<m[2] <<fine;

L'output è coniglio dall'indice zero. m[1] e m[2] sono vuoti.

Raggruppamenti

Quando sono coinvolti i gruppi, il modello completo abbinato va nella cella zero dell'array speciale. La successiva sottostringa trovata va nella cella 1; la sottostringa che segue, va nella cella 2; e così via. Il codice seguente lo illustra:

Se (regex_search('Il miglior libraio di oggi!',m,regex('libro ((sel) (ler))')))

costo<<m[0] <<fine;

costo<<m[1] <<fine;

costo<<m[2] <<fine;

costo<<m[3] <<fine;

L'uscita è:

libraio

venditore

cellula

leggere

Nota che il gruppo (venditore) viene prima del gruppo (sel).

Posizione della partita

È possibile conoscere la posizione della corrispondenza per ogni sottostringa nell'array cmatch. Il conteggio inizia dal primo carattere della stringa di destinazione, alla posizione zero. Il codice seguente lo illustra:

cmatch m;

Se (regex_search('Il miglior libraio di oggi!',m,regex('libro ((sel) (ler))')))

costo<<m[0] << '->' <<m.posizione(0) <<fine;

costo<<m[1] << '->' <<m.posizione(1) <<fine;

costo<<m[2] << '->' <<m.posizione(2) <<fine;

costo<<m[3] << '->' <<m.posizione(3) <<fine;

Notare l'uso della proprietà position, con l'indice di cella, come argomento. L'uscita è:

libraio->5

venditore->9

cellula->9

leggere->12

Cerca e sostituisci

Una nuova parola o frase può sostituire la corrispondenza. La funzione regex_replace() viene utilizzata per questo. Tuttavia, questa volta, la stringa in cui si verifica la sostituzione è l'oggetto stringa, non il letterale stringa. Quindi, la libreria di stringhe deve essere inclusa nel programma. Illustrazione:

#includere

#includere

#includere

usando lo spazio dei nomi std;

intprincipale()
{
stringa stringa= «Ecco, arriva il mio uomo. Ecco il tuo uomo».;
stringa newStr=regex_replace(P,regex('uomo'), 'donna');
costo<<nuovoStr<<fine;

Restituzione 0;
}

La funzione regex_replace(), come codificata qui, sostituisce tutte le corrispondenze. Il primo argomento della funzione è il target, il secondo è l'oggetto regex e il terzo è la stringa di sostituzione. La funzione restituisce una nuova stringa, che è la destinazione ma ha la sostituzione. L'uscita è:

Ecco la mia donna. Ecco la tua donna.

Conclusione

L'espressione regolare utilizza i modelli per abbinare le sottostringhe nella stringa della sequenza di destinazione. I modelli hanno metacaratteri. Le funzioni comunemente usate per le espressioni regolari C++ sono: regex_search(), regex_match() e regex_replace(). Una regex è un modello tra virgolette. Tuttavia, queste funzioni accettano l'oggetto regex come argomento e non solo l'espressione regolare. L'espressione regolare deve essere trasformata in un oggetto regolare prima che queste funzioni possano utilizzarla.