Conceptes bàsics d’expressió regular a C ++

Regular Expression Basics C



Penseu en la frase següent entre cometes:

'Aquí està el meu home'.

Aquesta cadena pot estar dins de l’ordinador i és possible que l’usuari vulgui saber si té la paraula home. Si té la paraula home, pot ser que vulgui canviar la paraula home per dona; de manera que la cadena ha de llegir:







'Aquí està la meva dona'.

Hi ha molts altres desitjos com aquests de l'usuari de l'ordinador; alguns són complexos. L'expressió regular, abreujada, regex, és el tema del tractament d'aquests problemes per l'ordinador. C ++ ve amb una biblioteca anomenada regex. Per tant, un programa C ++ per gestionar l’expressió regular hauria de començar per:



#incloure

#incloure

utilitzant l'espai de noms std;

En aquest article s’expliquen els conceptes bàsics de l’expressió regular a C ++.



Contingut de l'article

Fonaments d’expressió regular

Regex

Una cadena com Here is my man. a sobre hi ha la seqüència de destinació o la cadena de destinació o, simplement, la destinació. l'home, que es va cercar, és l'expressió regular o, simplement, l'expressió regular.





Coincidència

Es diu que la coincidència es produeix quan es troba la paraula o frase que es busca. Després de coincidir, es pot fer una substitució. Per exemple, després de situar-se l’home a sobre, es pot substituir per una dona.

Coincidència simple

El programa següent mostra com es fa coincidir la paraula home.



#incloure

#incloure

utilitzant l'espai de noms std;

intprincipal()
{

regex reg('home');
si (regex_search('Aquí està el meu home'.,reg))
cost<< 'coincident' <<endl;
en cas contrari
cost<< 'no coincideix' <<endl;

tornar 0;
}

La funció regex_search () retorna true si hi ha una coincidència i torna false si no es produeix cap coincidència. Aquí, la funció adopta dos arguments: el primer és la cadena de destinació i el segon és l’objecte regex. La pròpia regla és 'home', entre cometes dobles. La primera sentència de la funció main () forma l'objecte regex. Regex és un tipus i reg és l’objecte regex. La sortida del programa anterior es troba 'coincident', ja que es veu 'home' a la cadena de destinació. Si no es veiés 'home' a l'objectiu, regex_search () hauria tornat fals i la sortida 'no hauria coincidit'.

La sortida del codi següent no coincideix:

regex reg('home');
si (regex_search('Aquí està el que faig'.,reg))
cost<< 'coincident' <<endl;
en cas contrari
cost<< 'no coincideix' <<endl;

No coincideix perquè no s'ha pogut trobar l'expressió regular 'man' a tota la cadena de destinació 'Aquí està el meu procés'.

Patró

L’expressió regular, home per sobre, és molt senzilla. Els regexes no solen ser tan senzills. Les expressions regulars tenen metacaràcters. Els metacaràcters són personatges amb significats especials. Un metacaracter és un personatge sobre personatges. Els metacaràcters de l’expressió regular C ++ són:

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

Una regla regular, amb o sense metacaracters, és un patró.

Classes de personatges

Claudàtors

Un patró pot tenir caràcters entre claudàtors. Amb això, una posició particular a la cadena de destinació coincidiria amb qualsevol dels caràcters dels claudàtors. Penseu en els objectius següents:

'El gat és a l'habitació.'

'El ratpenat és a l'habitació.'

—La rata és a l'habitació.

La regla regular, [cbr] at coincidiria amb el gat del primer objectiu. Igualaria bat en el segon objectiu. Igualaria rata al tercer objectiu. Això es deu al fet que, gat o ratpenat o rata comença per 'c' o 'b' o 'r'. El següent segment de codi ho il·lustra:

regex reg('[cbr] a');
si (regex_search('El gat és a l'habitació.',reg))
cost<< 'coincident' <<endl;
si (regex_search('El ratpenat és a l'habitació.',reg))
cost<< 'coincident' <<endl;
si (regex_search(—La rata és a l'habitació.,reg))
cost<< 'coincident' <<endl;

La sortida és:

coincident

coincident

coincident

Gamma de personatges

La classe, [cbr] del patró [cbr], coincidiria amb diversos personatges possibles de l'objectiu. Coincidiria amb 'c' o 'b' o 'r' a l'objectiu. Si l'objectiu no té cap 'c', 'b' o 'r', seguit per a, no hi haurà cap coincidència.

Hi ha algunes possibilitats com ara 'c' o 'b' o 'r' en un interval. L'interval de dígits, del 0 al 9 té 10 possibilitats, i el patró per a això és [0-9]. El rang d'alfabets en minúscula, de la a a la z, té 26 possibilitats i el patró per a això és [a-z]. L’interval d’alfabet en majúscules, de la A a la Z, té 26 possibilitats i el patró per a això és [A-Z]. - no és oficialment un metacaracter, però entre claudàtors indicaria un interval. Per tant, el següent produeix una coincidència:

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

cost<< 'coincident' <<endl;

Fixeu-vos com s’ha construït la regla regular com a segon argument. La coincidència es produeix entre el dígit, 6 a l'interval, 0 a 9, i el 6 a l'objectiu, ID6id. El codi anterior equival a:

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

cost<< 'coincident' <<endl;

El codi següent produeix una coincidència:

charpàg[] = 'ID6iE';

si (regex_search(pàg,regex('[a-z]')))

cost<< 'coincident' <<endl;

Tingueu en compte que el primer argument aquí és una variable de cadena i no el literal de cadena. La coincidència és entre ‘i’ a ​​[a-z] i ‘i’ a ​​ID6iE.

No oblideu que una gamma és una classe. Hi pot haver text a la dreta del rang o a l’esquerra del rang al patró. El codi següent produeix una coincidència:

si (regex_search('ID2id és un identificador ',regex('ID [0-9] id')))

cost<< 'coincident' <<endl;

La coincidència és entre ID [0-9] id i ID2id. La resta de la cadena de destinació, és un identificador, no coincideix en aquesta situació.

Tal com s’utilitza en el tema de l’expressió regular (regexes), la paraula classe significa en realitat un conjunt. És a dir, un dels personatges del conjunt és que coincideixi.

Nota: el guionet - és un metacaracter només entre claudàtors, que indica un interval. No és un metacaracter a la regió, fora dels claudàtors.

Negació

Es pot negar una classe que inclogui un interval. És a dir, cap dels personatges del conjunt (classe) hauria de coincidir. Això s'indica amb el ^ metacaracter al principi del patró de classe, just després del claudàtor d'obertura. Per tant, [^ 0-9] significa fer coincidir el caràcter a la posició adequada de l'objectiu, que no és cap caràcter de l'interval, del 0 al 9 inclosos. Per tant, el següent codi no produirà cap coincidència:

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

cost<< 'coincident' <<endl;

en cas contrari

cost<< 'no coincideix' <<endl;

Es pot trobar un dígit dins de l'interval de 0 a 9 en qualsevol de les posicions de la cadena de destinació, 0123456789101112 ,; per tant, no hi ha negació de coincidència.

El codi següent produeix una coincidència:

si (regex_search('ABCDEFGHIJ',regex('[^ 0-9]')))

cost<< 'coincident' <<endl;

No s'ha pogut trobar cap dígit a l'objectiu, ABCDEFGHIJ ,; així que hi ha un partit.

[a-z] és un interval fora de [^ a-z]. I per tant [^ a-z] és la negació de [a-z].

[A-Z] és un interval fora de [^ A-Z]. I per tant [^ A-Z] és la negació de [A-Z].

Existeixen altres negacions.

Espais en blanc coincidents

'' O t o r o n o f és un caràcter d'espai en blanc. Al codi següent, l'expressió regular n coincideix amb ' n' a l'objectiu:

si (regex_search(De primera línia. r nDe la línia dos.,regex(' n')))

cost<< 'coincident' <<endl;

Coincideix amb qualsevol personatge en blanc

El patró o la classe que coincideix amb qualsevol caràcter d'espai en blanc és, [ t r n f]. Al codi següent, coincideix '':

si (regex_search('un dos',regex('[ t r n f] ')))

cost<< 'coincident' <<endl;

Coincideix amb qualsevol personatge que no sigui en blanc

El patró o la classe que coincideix amb qualsevol caràcter d'espai no blanc és, [^ t r n f]. El codi següent produeix una coincidència perquè no hi ha espai en blanc a l'objectiu:

si (regex_search('1234abcd',regex('[^ t r n f] ')))

cost<< 'coincident' <<endl;

El punt (.) Del patró

El punt (.) Del patró coincideix amb qualsevol caràcter inclòs ell mateix, excepte n, a l'objectiu. Es produeix una coincidència al codi següent:

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

cost<< 'coincident' <<endl;

No hi ha resultats coincidents al codi següent perquè l'objectiu és n.

si (regex_search(' n',regex('.')))

cost<< 'coincident' <<endl;

en cas contrari

cost<< 'no coincideix' <<endl;

Nota: dins d'una classe de caràcters amb claudàtors, el punt no té cap significat especial.

Repeticions coincidents

Un caràcter o un grup de caràcters poden aparèixer més d'una vegada dins de la cadena de destinació. Un patró pot coincidir amb aquesta repetició. Els metacaràcters,?, *, + I {} s'utilitzen per fer coincidir la repetició a l'objectiu. Si x és un caràcter d'interès de la cadena de destinació, els metacaràcters tenen el significat següent:

x*:significa partit'X' 0o més vegades,jo.I.,qualsevol nombre de vegades

x+:significa partit'X' 1o més vegades,jo.I.,al menys un cop

x? :significa partit'X' 0o bé1 temps

x{n,}:significa partit'X'almenys n o més vegades.Notala coma.

x{n} :partit'X'exactament n vegades

x{n,m}:partit'X'almenys n vegades,però no més de m vegades.

Aquests metacaracteres es diuen quantificadors.

Il·lustracions

*

El * coincideix amb el caràcter o el grup precedents, zero o més vegades. o * coincideix amb 'o' en el gos de la cadena de destinació. També coincideix amb oo al llibre i al look. La regex, o * coincideix amb boooo a L’animal va booooed .. Nota: o * coincideix amb dig, on ‘o’ té zero (o més) temps.

+

El + coincideix amb el caràcter o el grup precedents, 1 o més vegades. Contrasteu-lo amb zero o més vegades per a *. Per tant, l’expressió regular, e + coincideix amb ‘e’ a eat, on ‘e’ es produeix una vegada. e + també coincideix amb ee en ovelles, on ‘e’ es produeix més d’una vegada. Nota: e + no coincidirà amb l'excavació perquè a l'excavació 'e' no es produeix almenys una vegada.

?

El? coincideix amb el caràcter o el grup precedents, 0 o 1 vegada (i no més). Llavors, e? coincideix amb l'excavació perquè 'e' es produeix en l'excavació, temps zero. e? coincidències establertes perquè 'e' es produeix al conjunt, una vegada. Nota: e? encara coincideix amb ovelles; tot i que hi ha dues ‘e’ a les ovelles. Aquí hi ha un matís (vegeu més endavant).

{n,}

Això coincideix amb almenys n repeticions consecutives d'un caràcter o grup precedents. Per tant, l’expressió regular, e {2,} coincideix amb les dues ‘e’ a l’objectiu, ovelles, i les tres ‘e’ a les ovelles objectiu. e {2,} no coincideix amb el conjunt, perquè el conjunt només té una 'e'.

{n}

Això coincideix exactament amb n repeticions consecutives d'un caràcter o grup precedents. Per tant, l’expressió regular, e {2} coincideix amb les dues ‘e’ de l’objectiu, ovelles. e {2} no coincideix amb el conjunt perquè el conjunt només té una 'e'. Bé, e {2} coincideix amb dues ‘e’ a l’objectiu, ovelles. Aquí hi ha un matís (vegeu més endavant).

{n, m}

Això coincideix amb diverses repeticions consecutives d'un caràcter o grup precedents, des de n fins a m, inclosos. Per tant, e {1,3} no coincideix amb res a l'excavació, que no té cap 'e'. Coincideix amb la ‘e’ del conjunt, les dues ‘e’ a les ovelles, les tres ‘e’ a les ovelles i les tres ‘e’ a les ovelles. Hi ha un matís a l’últim partit (veure més endavant).

Alternança coincident

Penseu en la següent cadena de destinació a l'ordinador.

La granja té porcs de diferents mides.

El programador pot voler saber si aquest objectiu té cabra, conill o porc. El codi seria el següent:

charpàg[] = 'La granja té porcs de diferents mides'.;

si (regex_search(pàg,regex('cabra | conill | porc')))

cost<< 'coincident' <<endl;

en cas contrari

cost<< 'no coincideix' <<endl;

El codi produeix una coincidència. Tingueu en compte l'ús del caràcter alternatiu, |. Hi pot haver dues, tres, quatre i més opcions. C ++ primer intentarà fer coincidir la primera alternativa, la cabra, a cada posició de caràcters de la cadena de destinació. Si no té èxit amb la cabra, prova la següent alternativa, el conill. Si no té èxit amb el conill, prova la següent alternativa, el porc. Si el porc falla, llavors C ++ passa a la següent posició de l'objectiu i torna a començar amb la primera alternativa.

Al codi anterior, el porc coincideix.

Començament o final de la coincidència

Començament


Si ^ es troba a l'inici de l'expressió regular, el text inicial de la cadena de destinació es pot fer coincidir amb l'expressió regular. Al codi següent, l'inici de l'objectiu és abc, que coincideix:

si (regex_search('abc i def',regex('^ Abc')))

cost<< 'coincident' <<endl;

No es produeix cap coincidència al codi següent:

si (regex_search('Sí, abc i def',regex('^ Abc')))

cost<< 'coincident' <<endl;

en cas contrari

cost<< 'no coincideix' <<endl;

Aquí, abc no es troba al començament de l'objectiu.

Nota: el caràcter circumflex, '^', és un metacaracter a l'inici de l'expressió regular, que coincideix amb l'inici de la cadena de destinació. Encara és un metacaracter al començament de la classe de personatges, on nega la classe.

Final

Si $ és al final de l'expressió regular, el text final de la cadena de destinació es pot fer coincidir amb l'expressió regular. Al codi següent, el final de l'objectiu és xyz, que coincideix:

si (regex_search('uvw i xyz',regex('xyz $')))

cost<< 'coincident' <<endl;

No es produeix cap coincidència al codi següent:

si (regex_search('uvw i xyz final',regex('xyz $')))

cost<< 'coincident' <<endl;

en cas contrari

cost<< 'no coincideix' <<endl;

Aquí, xyz no es troba al final de l'objectiu.

Agrupació

Els parèntesis es poden utilitzar per agrupar personatges en un patró. Penseu en la següent expressió regular:

'un concert (pianista)'

El grup aquí és pianista envoltat de metacaracteres (i). En realitat és un subgrup, mentre que un concert (pianista) és tot el grup. Penseu en el següent:

'El (pianista és bo)'

Aquí, el subgrup o la subcorda són: el pianista és bo.

Subcadenes amb parts comunes

Un comptable és una persona que té cura dels llibres. Imagineu-vos una biblioteca amb un comptador i una prestatgeria. Suposem que una de les cadenes de destinació següents es troba a l'ordinador:

'La biblioteca té una prestatgeria admirable.';

'Aquí teniu el comptable.';

'El comptable treballa amb la prestatgeria.';

Suposem que l’interès del programador no és saber quina d’aquestes frases es troba a l’ordinador. Tot i així, el seu interès és saber si la prestatgeria o el comptador estan presents en qualsevol cadena objectiu que hi hagi a l’ordinador. En aquest cas, la seva expressió regular pot ser:

'prestatgeria | comptador.'

Utilitzant l’alternança.

Fixeu-vos que el llibre, que és comú a les dues paraules, s’ha escrit dues vegades, en les dues paraules del patró. Per evitar escriure dues vegades el llibre, la regla regular s'escriuria millor com:

'llibre (prestatge | guardià)'

Aquí, el grup, prestatgeria | El metacaracter alternatiu encara s'ha utilitzat, però no per a dues paraules llargues. S'ha utilitzat per a les dues parts finals de les dues paraules llargues. C ++ tracta un grup com una entitat. Per tant, C ++ buscarà un prestatge o un guarda que aparegui immediatament després del llibre. Es coincideix la sortida del codi següent:

charpàg[] = 'La biblioteca té una prestatgeria admirable'.;

si (regex_search(pàg,regex('llibre (prestatge | guardià)')))

cost<< 'coincident' <<endl;

prestatgeria i no comptador s’han coincidit.

L'icase i la línia múltiple regex_constants

icase

La coincidència distingeix entre majúscules i minúscules per defecte. Tanmateix, es pot distingir entre majúscules i minúscules. Per aconseguir-ho, utilitzeu la constant regex :: icase, com al codi següent:

si (regex_search('Comentaris',regex('alimentar',regex::icase)))

cost<< 'coincident' <<endl;

La sortida coincideix. Així, els comentaris amb ‘F’ en majúscules s’han coincidit amb els feed amb ‘f’ en minúscula. regex :: icase s'ha convertit en el segon argument del constructor regex (). Sense això, la declaració no produiria cap coincidència.

Multilínia

Penseu en el codi següent:

charpàg[] = 'línia 1 nlínia 2 nlínia 3 ';

si (regex_search(pàg,regex('^. * $')))

cost<< 'coincident' <<endl;

en cas contrari

cost<< 'no coincideix' <<endl;

La sortida no coincideix. L'expressió regular, ^. * $, Coincideix amb la cadena de destinació des del principi fins al final. . * significa qualsevol caràcter excepte n, zero o més vegades. Per tant, a causa dels caràcters de línia nova ( n) de l'objectiu, no hi ha cap coincidència.

L'objectiu és una cadena de línies múltiples. Per tal que ‘.’ Coincideixi amb el caràcter de nova línia, s’ha de fer la constant regex :: multiline, el segon argument de la construcció regex (). El següent codi ho il·lustra:

charpàg[] = 'línia 1 nlínia 2 nlínia 3 ';

si (regex_search(pàg,regex('^. * $',regex::multilínia)))

cost<< 'coincident' <<endl;

en cas contrari

cost<< 'no coincideix' <<endl;

Coincidència amb tota la cadena objectiu

Per fer coincidir tota la cadena de destinació, que no té el caràcter de línia nova ( n), es pot utilitzar la funció regex_match (). Aquesta funció és diferent de regex_search (). El següent codi ho il·lustra:

charpàg[] = 'primer, segon, tercer';

si (regex_match(pàg,regex('. * segon. *')))

cost<< 'coincident' <<endl;

Aquí hi ha un partit. Tanmateix, tingueu en compte que l’expressió regular coincideix amb tota la cadena de destinació i que la cadena de destinació no té cap « n».

L'objecte match_results

La funció regex_search () pot incloure un argument entre l'objecte regex i l'objectiu. Aquest argument és l'objecte match_results. Es pot conèixer tota la cadena coincident (part) i les subcadenes coincidents. Aquest objecte és una matriu especial amb mètodes. El tipus d’objecte match_results és cmatch (per a literals de cadena).

Obtenció de partits

Penseu en el codi següent:

charpàg[] = 'La dona que buscaves!';

cmatch m;

si (regex_search(pàg,m,regex('w.m.n')))

cost<<m[0] <<endl;

La cadena de destinació té la paraula dona. La sortida és dona ’, que correspon a la regió regular, w.m.n. A l’índex zero, la matriu especial té l’única coincidència, que és la dona.

Amb les opcions de classe, només s'envia a la matriu especial la primera cadena secundària que es troba a l'objectiu. El següent codi ho il·lustra:

cmatch m;

si (regex_search('La rata, el gat, el ratpenat!',m,regex('[bcr] a')))

cost<<m[0] <<endl;

cost<<m[1] <<endl;

cost<<m[2] <<endl;

La sortida és rata des de l’índex zero. m [1] i m [2] estan buits.

Amb alternatives, només s'envia a la matriu especial la primera sub-cadena que es troba a l'objectiu. El següent codi ho il·lustra:

si (regex_search('El conill, la cabra, el porc!',m,regex('cabra | conill | porc')))

cost<<m[0] <<endl;

cost<<m[1] <<endl;

cost<<m[2] <<endl;

La sortida és de conill de l’índex zero. m [1] i m [2] estan buits.

Agrupacions

Quan hi ha grups implicats, el patró complet coincideix amb la cel·la zero de la matriu especial. La següent subcadena trobada entra a la cel·la 1; la sub-cadena següent, entra a la cel·la 2; etcètera. El següent codi ho il·lustra:

si (regex_search('El millor llibreter d'avui!',m,regex('llibre ((sel) (ler))')))

cost<<m[0] <<endl;

cost<<m[1] <<endl;

cost<<m[2] <<endl;

cost<<m[3] <<endl;

La sortida és:

llibreter

venedor

cel·la

llegir

Tingueu en compte que el grup (venedor) passa per davant del grup (sel).

Posició del partit

Es pot conèixer la posició de la coincidència per a cada sub-cadena de la matriu cmatch. El recompte comença a partir del primer caràcter de la cadena objectiu, a la posició zero. El següent codi ho il·lustra:

cmatch m;

si (regex_search('El millor llibreter d'avui!',m,regex('llibre ((sel) (ler))')))

cost<<m[0] << '->' <<m.posició(0) <<endl;

cost<<m[1] << '->' <<m.posició(1) <<endl;

cost<<m[2] << '->' <<m.posició(2) <<endl;

cost<<m[3] << '->' <<m.posició(3) <<endl;

Tingueu en compte l’ús de la propietat de posició, amb l’índex de cel·la, com a argument. La sortida és:

llibreter->5

venedor->9

cel·la->9

llegir->12

Cerca i substitució

Una nova paraula o frase pot substituir la coincidència. Per a això s'utilitza la funció regex_replace (). Tanmateix, aquesta vegada, la cadena on es produeix la substitució és l'objecte cadena, no la cadena literal. Per tant, la biblioteca de cadenes s’ha d’incloure al programa. Il·lustració:

#incloure

#incloure

#incloure

utilitzant l'espai de noms std;

intprincipal()
{
corda str= —Aquí ve el meu home. Aquí va el teu home.;
cadena newStr=regex_replace(pàg,regex('home'), 'dona');
cost<<newStr<<endl;

tornar 0;
}

La funció regex_replace (), tal com es codifica aquí, substitueix totes les coincidències. El primer argument de la funció és l'objectiu, el segon és l'objecte regex i el tercer és la cadena de reemplaçament. La funció retorna una cadena nova, que és l'objectiu, però que en té el reemplaçament. La sortida és:

Aquí ve la meva dona. Aquí va la teva dona.

Conclusió

L’expressió regular utilitza patrons per fer coincidir les subcadenes de la cadena de seqüència de destinació. Els patrons tenen metacaràcters. Les funcions més utilitzades per a expressions regulars de C ++ són: regex_search (), regex_match () i regex_replace (). Una expressió regular és un patró entre cometes dobles. Tot i això, aquestes funcions prenen com a argument l’objecte regex i no només el regex. L'expressió regular s'ha de convertir en un objecte d'expressió regular abans que aquestes funcions puguin utilitzar-la.