Osnove regularnog izraza u C ++

Regular Expression Basics C

Razmotrite sljedeću rečenicu pod navodnicima:

'Evo mog čovjeka.'

Ovaj niz može biti unutar računala, pa će korisnik možda htjeti znati ima li riječ man. Ako ima riječ muškarac, možda će htjeti promijeniti riječ muškarac u žena; tako da niz treba glasiti:



'Evo moje žene.'

Postoje mnoge druge želje poput ovih korisnika računala; neki su složeni. Regularni izraz, skraćeno regex, predmet je rješavanja ovih problema putem računala. C ++ dolazi s bibliotekom koja se zove regex. Dakle, C ++ program za rukovanje regularnim izrazom trebao bi početi s:



#uključi

#uključi

koristeći imenski prostor std;

Ovaj članak objašnjava osnove regularnog izraza u C ++.



Sadržaj članka

Osnove regularnog izražavanja

Regularni izraz

Žica poput Here is my man. gore je ciljni niz ili ciljni niz ili jednostavno, cilj. man, za kojim se tragalo, regularni je izraz ili jednostavno regex.

Podudaranje

Podudaranje se događa kada se riječ ili izraz koji se traži nalazi. Nakon podudaranja, može doći do zamjene. Na primjer, nakon što se muškarac nalazi iznad, može ga zamijeniti žena.

Jednostavno podudaranje

Sljedeći program prikazuje kako se podudara riječ čovjek.



#uključi

#uključi

koristeći imenski prostor std;

intglavni()
{

regex reg('čovjek');
ako (regex_search('Evo mog čovjeka.',reg))
trošak<< 'podudarno' <<endl;
drugo
trošak<< 'nema podudaranja' <<endl;

povratak 0;
}

Funkcija regex_search () vraća true ako postoji podudaranje i vraća false ako nema podudaranja. Ovdje funkcija uzima dva argumenta: prvi je ciljni niz, a drugi je regex objekt. Sam regex je 'čovjek', u dvostrukim navodnicima. Prvi izraz u funkciji main () tvori regex objekt. Regex je tip, a reg je regex objekt. Izlaz gornjeg programa je 'uparen', jer se 'man' vidi u ciljnom nizu. Da se 'man' ne vidi u cilju, regex_search () bi vratio false, a izlaz bi bio 'not match'.

Izlaz sljedećeg koda se ne podudara:

regex reg('čovjek');
ako (regex_search('Evo moje izrade.',reg))
trošak<< 'podudarno' <<endl;
drugo
trošak<< 'nema podudaranja' <<endl;

Ne podudara se jer se regex 'man' ne može pronaći u cijelom ciljnom nizu, 'Evo mog stvaranja.'

Uzorak

Regularni izraz, čovjek gore, vrlo je jednostavan. Redovni izrazi obično nisu tako jednostavni. Regularni izrazi imaju metakaraktere. Metaznakovi su likovi s posebnim značenjem. Metakarakter je lik o likovima. C ++ regex metaznakovi su:

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

Redovni izraz, sa ili bez metaznakova, uzorak je.

Klase likova

Uglate zagrade

Uzorak može imati znakove unutar uglatih zagrada. Time bi se određeni položaj u ciljnom nizu podudarao s bilo kojim od znakova uglatih zagrada. Uzmite u obzir sljedeće ciljeve:

'Mačka je u sobi.'

'Šišmiš je u sobi.'

'Štakor je u sobi.'

Regularni izraz, [cbr] at bi odgovarao mački u prvoj meti. To bi odgovaralo palici u drugoj meti. Odgovarao bi štakoru u trećoj meti. To je zato što mačka, šišmiš ili štakor počinju s 'c' ili 'b' ili 'r'. Sljedeći segment koda to ilustrira:

regex reg('[cbr] u');
ako (regex_search('Mačka je u sobi.',reg))
trošak<< 'podudarno' <<endl;
ako (regex_search('Šišmiš je u sobi.',reg))
trošak<< 'podudarno' <<endl;
ako (regex_search('Štakor je u sobi.',reg))
trošak<< 'podudarno' <<endl;

Izlaz je:

podudarno

podudarno

podudarno

Raspon likova

Klasa, [cbr] u uzorku [cbr], odgovarala bi nekoliko mogućih znakova u cilju. To bi odgovaralo 'c' ili 'b' ili 'r' u meti. Ako cilj ne sadrži ništa od 'c' ili 'b' ili 'r', iza kojeg slijedi at, ne bi bilo podudaranja.

Neke mogućnosti poput 'c' ili 'b' ili 'r' postoje u rasponu. Raspon znamenki, od 0 do 9, ima 10 mogućnosti, a uzorak za to je [0-9]. Raspon malih slova, a do z, ima 26 mogućnosti, a uzorak za to je [a-z]. Raspon velikih slova, od A do Z, ima 26 mogućnosti, a uzorak za to je [A-Z]. - službeno nije metaznak, ali u uglatim zagradama označava raspon. Dakle, sljedeće proizvodi podudaranje:

ako (regex_search('ID6id',regeks('[0-9]')))

trošak<< 'podudarno' <<endl;

Zapazite kako je regeks konstruiran kao drugi argument. Podudaranje se događa između znamenke 6 u rasponu, 0 do 9 i 6 u cilju, ID6id. Gornji kôd ekvivalentan je:

ako (regex_search('ID6id',regeks('[0123456789]')))

trošak<< 'podudarno' <<endl;

Sljedeći kôd proizvodi podudaranje:

charstr[] = 'ID6iE';

ako (regex_search(str,regeks('[a-z]')))

trošak<< 'podudarno' <<endl;

Imajte na umu da je prvi argument ovdje string varijabla, a ne literal niza. Podudaranje je između 'i' u [a-z] i 'i' u ID6iE.

Ne zaboravite da je raspon klasa. Može biti tekst desno od raspona ili lijevo od raspona u uzorku. Sljedeći kôd proizvodi podudaranje:

ako (regex_search('ID2id je osobna iskaznica ',regeks('ID [0-9] ID')))

trošak<< 'podudarno' <<endl;

Podudaranje je između ID [0-9] id i ID2id. Ostatak ciljnog niza je ID, u ovoj se situaciji ne podudara.

Kako se koristi u subjektu regularnog izraza (regeks), riječ klasa zapravo znači skup. Odnosno, jedan od likova u setu mora odgovarati.

Napomena: crtica - je metaznak samo unutar uglatih zagrada, što označava raspon. Nije metaznak u regularnom izrazu, izvan uglatih zagrada.

Negacija

Klasa koja uključuje raspon može se negirati. Odnosno, nijedan od znakova u skupu (klasi) ne bi se trebao podudarati. To je označeno metaznakom ^ na početku uzorka klase, odmah nakon uglate zagrade. Dakle, [^0-9] znači podudaranje znaka na odgovarajućoj poziciji u cilju, što nije bilo koji znak u rasponu, uključujući 0 do 9. Dakle, sljedeći kôd neće proizvesti podudaranje:

ako (regex_search('0123456789101112',regeks('[^ 0-9]')))

trošak<< 'podudarno' <<endl;

drugo

trošak<< 'nema podudaranja' <<endl;

U bilo kojem od ciljnih položaja niza može se pronaći znamenka unutar raspona od 0 do 9, 0123456789101112 ,; pa nema podudaranja - negacije.

Sljedeći kôd proizvodi podudaranje:

ako (regex_search('ABCDEFGHIJ',regeks('[^ 0-9]')))

trošak<< 'podudarno' <<endl;

Nijedna znamenka nije pronađena u meti, ABCDEFGHIJ ,; pa postoji podudarnost.

[a-z] je raspon izvan [^a-z]. I tako je [^a-z] negacija [a-z].

[A-Z] je raspon izvan [^A-Z]. I tako je [^A-Z] negacija [A-Z].

Postoje i druge negacije.

Podudaranje bijelih prostora

‘’ Ili t ili r ili n ili f je znak razmaka. U sljedećem kodu regularni izraz n odgovara ' n' u cilju:

ako (regex_search(»Od prve linije. r nRed dva. ',regeks(' n')))

trošak<< 'podudarno' <<endl;

Odgovara bilo kojem znaku razmaka

Uzorak ili klasa koja odgovaraju bilo kojem znaku razmaka je, [ t r n f]. U sljedećem kodu, '' se podudara:

ako (regex_search('jedan dva',regeks('[ t r n f] ')))

trošak<< 'podudarno' <<endl;

Podudaranje s bilo kojim znakom koji nije prazan prostor

Uzorak ili klasa koja odgovaraju bilo kojem znaku koji nije razmak je: [^ t r n f]. Sljedeći kôd proizvodi podudaranje jer u cilju nema razmaka:

ako (regex_search('1234abcd',regeks('[^ t r n f] ')))

trošak<< 'podudarno' <<endl;

Točka (.) U uzorku

Točka (.) U uzorku podudara se s bilo kojim znakom, uključujući i samog sebe, osim n, u cilju. Podudaranje se proizvodi u sljedećem kodu:

ako (regex_search('1234abcd',regeks('.')))

trošak<< 'podudarno' <<endl;

Nema rezultata u sljedećem kodu jer je cilj n.

ako (regex_search(' n',regeks('.')))

trošak<< 'podudarno' <<endl;

drugo

trošak<< 'nema podudaranja' <<endl;

Napomena: Unutar klase znakova s ​​uglatim zagradama točka nema posebno značenje.

Podudaranje ponavljanja

Znak ili skupina znakova može se pojaviti više puta unutar ciljnog niza. Uzorak može odgovarati ovom ponavljanju. Metaznakovi,?, *, +I {} koriste se za podudaranje ponavljanja u cilju. Ako je x zanimljiv znak u ciljnom nizu, tada metaznakovi imaju sljedeće značenje:

x*:znači utakmica'x' 0ili više puta,i.I.,bilo koji broj puta

x+:znači utakmica'x' 1ili više puta,i.I.,barem jednom

x? :znači utakmica'x' 0ili1 vrijeme

x{n,}:znači utakmica'x'barem n ili više puta.Bilješkazarez.

x{n} :podudarati'x'točno n puta

x{n,m}:podudarati'x'barem n puta,ali ne više od m puta.

Ti se metaznakovi nazivaju kvantifikatore.

Ilustracije

*

* Odgovara prethodnom znaku ili prethodnoj skupini, nula ili više puta. o* podudara se s 'o' u pasu ciljnog niza. Također se podudara s oo u knjizi i izgledu. Redovni izraz, o* podudara se s booooom u Životinja booooed .. Napomena: o* podudara se s kopanjem, gdje se 'o' pojavljuje nula (ili više) vremena.

+

Znak + odgovara prethodnom znaku ili prethodnoj skupini, 1 ili više puta. Usporedite to s nulom ili više puta za *. Dakle, regex, e+ podudara se s 'e' u jelu, gdje se 'e' pojavljuje jednom. e+ također odgovara ee kod ovaca, gdje se 'e' javlja više puta. Napomena: e+ neće se podudarati s digom jer se u digu 'e' ne pojavljuje barem jednom.

?

The? odgovara prethodnom znaku ili prethodnoj skupini, 0 ili 1 put (i ne više). Dakle, e? podudara se dig jer se 'e' pojavljuje u dig, nula vremena. e? podudara se jer se 'e' pojavljuje u skupu, jednokratno. Napomena: e? još uvijek odgovara ovcama; iako u ovaca postoje dva ‘e’. Ovdje postoji jedna nijansa - pogledajte kasnije.

{n,}

Ovo odgovara najmanje n uzastopnih ponavljanja prethodnog znaka ili prethodne grupe. Dakle, regex, e {2,} podudara se s dva 'e' u meti, ovce, i tri 'e' u ciljnom ovcu. e {2,} se ne podudara sa skupom jer skup ima samo jedno 'e'.

{n}

To odgovara točno n uzastopnih ponavljanja prethodnog znaka ili prethodne grupe. Dakle, regex, e {2} podudara se s dva 'e' u cilju, ovce. e {2} ne podudara se sa skupom jer skup ima samo jedno 'e'. Pa, e {2} podudara se s dva 'e' u meti, ovce. Ovdje postoji jedna nijansa - pogledajte kasnije.

{n, m}

Ovo odgovara nekoliko uzastopnih ponavljanja prethodnog znaka ili prethodne grupe, bilo gdje od n do uključivo. Dakle, e {1,3} ne podudara se s ništa u dig -u, koje nema 'e'. Odgovara jednom 'e' u skupu, dva 'e' u ovcama, tri 'e' u ovcama i tri 'e' u ovcama. Na posljednjoj utakmici postoji jedna nijansa - pogledajte kasnije.

Podudaranje alternacije

Razmislite o sljedećem ciljnom nizu u računalu.

Na farmi se nalaze svinje različitih veličina.

Programer će možda htjeti znati ima li ova meta kozu, zeca ili svinju. Kod bi bio sljedeći:

charstr[] = 'Farma ima svinje različitih veličina.';

ako (regex_search(str,regeks('koza | zec | svinja')))

trošak<< 'podudarno' <<endl;

drugo

trošak<< 'nema podudaranja' <<endl;

Kôd proizvodi podudaranje. Obratite pozornost na upotrebu znaka izmjene, |. Mogu postojati dvije, tri, četiri i više opcija. C ++ prvo će pokušati uskladiti prvu alternativu, kozu, na svakoj poziciji znaka u ciljnom nizu. Ako ne uspije s kozom, pokušava sljedeću alternativu, zec. Ako ne uspije sa zecom, pokušava sljedeću alternativu, svinju. Ako svinja ne uspije, tada C ++ prelazi na sljedeću poziciju u meti i ponovno počinje s prvom alternativom.

U gornjem kodu svinja se podudara.

Podudaranje početka ili kraja

Početak


Ako je ^ na početku regularnog izraza, tada se regularni izraz može uskladiti s početnim tekstom ciljnog niza. U sljedećem kodu početak cilja je abc, što se podudara:

ako (regex_search('abc i def',regeks('^ abc')))

trošak<< 'podudarno' <<endl;

Nema podudaranja u sljedećem kodu:

ako (regex_search('Da, abc i def',regeks('^ abc')))

trošak<< 'podudarno' <<endl;

drugo

trošak<< 'nema podudaranja' <<endl;

Ovdje abc nije na početku cilja.

Napomena: Cirkumsfleksni znak, ‘^’, je metakarakter na početku regularnog izraza, koji odgovara početku ciljnog niza. Još uvijek je metakarakter na početku klase znakova, gdje negira klasu.

Kraj

Ako je $ na kraju regularnog izraza, tada se regularni izraz može uskladiti s završnim tekstom ciljnog niza. U sljedećem kodu kraj cilja je xyz, što se podudara:

ako (regex_search('uvw i xyz',regeks('xyz $')))

trošak<< 'podudarno' <<endl;

Nema podudaranja u sljedećem kodu:

ako (regex_search('uvw i xyz final',regeks('xyz $')))

trošak<< 'podudarno' <<endl;

drugo

trošak<< 'nema podudaranja' <<endl;

Ovdje xyz nije na kraju mete.

Grupiranje

Zagrade se mogu koristiti za grupiranje znakova u uzorak. Razmislite o sljedećem regularnom izrazu:

'koncert (pijanist)'

Ovdje je skupina pijanistica okružena metakarakterima (i). To je zapravo podgrupa, dok je koncert (pijanist) cijela grupa. Uzmite u obzir sljedeće:

'(Pijanist je dobar)'

Ovdje, podgrupa ili podniz je, pijanist je dobar.

Podnizovi sa zajedničkim dijelovima

Knjigovođa je osoba koja se brine o knjigama. Zamislite knjižnicu s knjigovođom i policom za knjige. Pretpostavimo da je jedan od sljedećih ciljnih nizova u računalu:

'Knjižnica ima policu s knjigama koje se dive.';

'Ovdje je knjigovođa.';

'Knjigovođa radi s policom za knjige.';

Pretpostavimo da interes programera nije znati koja se od ovih rečenica nalazi u računalu. Ipak, njegov je interes znati je li polica ili knjigovođa prisutna u bilo kojem ciljnom nizu u računalu. U ovom slučaju njegov regeks može biti:

'polica za knjige | knjigovođa.'

Korištenje izmjene.

Primijetite da je knjiga, koja je zajednička za obje riječi, dvaput otkucana, s dvije riječi u uzorku. Da biste izbjegli tipkanje knjige dva puta, regex bi bilo bolje napisati kao:

'knjiga (polica | čuvar)'

Ovdje, grupa, polica | čuvar metaznaka izmjene još se koristi, ali ne za dvije duge riječi. Korišten je za dva završna dijela dviju dugih riječi. C ++ tretira grupu kao entitet. Dakle, C ++ će tražiti policu ili čuvara koji dolazi odmah nakon knjige. Ispis sljedećeg koda se podudara:

charstr[] = 'Knjižnica ima policu s knjigama koje se dive.';

ako (regex_search(str,regeks('knjiga (polica | čuvar)')))

trošak<< 'podudarno' <<endl;

polica knjiga, a ne knjigovođa.

Icase i multiline regex_constants

icase

Podudaranje prema zadanim postavkama razlikuje velika i mala slova. Međutim, može se učiniti osjetljivim na velika i mala slova. Da biste to postigli, koristite konstantu regex :: icase, kao u sljedećem kodu:

ako (regex_search('Povratne informacije',regeks('hraniti',regeks::icase)))

trošak<< 'podudarno' <<endl;

Izlaz je usklađen. Dakle, povratne informacije s velikim slovima 'F' usklađene su s feedovima s malim slovima 'f'. regex :: icase je postao drugi argument konstruktora regex (). Bez toga izjava ne bi dala podudarnost.

Multiline

Uzmite u obzir sljedeći kod:

charstr[] = 'linija 1 nredak 2 nredak 3 ';

ako (regex_search(str,regeks('^. * $')))

trošak<< 'podudarno' <<endl;

drugo

trošak<< 'nema podudaranja' <<endl;

Izlaz se ne podudara. Regularni izraz, ^.*$, Podudara se s ciljnim nizom od njegova početka do kraja. .* znači bilo koji znak osim n, nula ili više puta. Dakle, zbog znakova novog retka ( n) u cilju nije bilo podudaranja.

Cilj je višeredni niz. Da bi '.' Odgovaralo znaku novog retka, mora se napraviti konstantan regex :: multiline, drugi argument konstrukcije regex (). Sljedeći kod to ilustrira:

charstr[] = 'linija 1 nredak 2 nredak 3 ';

ako (regex_search(str,regeks('^. * $',regeks::višelinijski)))

trošak<< 'podudarno' <<endl;

drugo

trošak<< 'nema podudaranja' <<endl;

Usklađivanje cijelog niza meta

Za slaganje cijelog niza cilja, koji nema znak novog retka ( n), može se koristiti funkcija regex_match (). Ova se funkcija razlikuje od regex_search (). Sljedeći kod to ilustrira:

charstr[] = 'prvi drugi treći';

ako (regex_match(str,regeks('.*drugi.*')))

trošak<< 'podudarno' <<endl;

Ovdje postoji podudarnost. Međutim, imajte na umu da se regex podudara s cijelim ciljnim nizom, a ciljni niz nema nikakav ‘ n’.

Objekt match_results

Funkcija regex_search () može uzeti argument između cilja i regex objekta. Ovaj argument je objekt match_results. Cijeli podudarni (dio) niz i podudarani podnizovi mogu biti poznati s njim. Ovaj objekt je poseban niz s metodama. Vrsta objekta match_results je cmatch (za literalne znakove).

Dobivanje šibica

Uzmite u obzir sljedeći kod:

charstr[] = 'Žena koju ste tražili!';

podudaranje m;

ako (regex_search(str,m,regeks('w.m.n')))

trošak<<m[0] <<endl;

Ciljni niz ima riječ žena. Izlaz je žena ', što odgovara regularnom izrazu, w.m.n. Kod indeksa nula, poseban niz sadrži jedino podudaranje, a to je žena.

S opcijama klase, samo prvi podniz koji se nalazi u cilju šalje se u poseban niz. Sljedeći kod to ilustrira:

podudaranje m;

ako (regex_search('Štakor, mačka, šišmiš!',m,regeks('[bcr] u')))

trošak<<m[0] <<endl;

trošak<<m[1] <<endl;

trošak<<m[2] <<endl;

Izlaz je štakor s nula indeksa. m [1] i m [2] su prazni.

S alternativama, samo prvi podniz koji se nalazi u cilju šalje se u poseban niz. Sljedeći kod to ilustrira:

ako (regex_search('Zec, koza, svinja!',m,regeks('koza | zec | svinja')))

trošak<<m[0] <<endl;

trošak<<m[1] <<endl;

trošak<<m[2] <<endl;

Izlaz je zec iz indeksa nula. m [1] i m [2] su prazni.

Grupisanja

Kad su uključene grupe, potpuni uzorak koji se podudara ide u nulu ćelije posebnog niza. Sljedeći pronađeni podniz dolazi u ćeliju 1; podniz koji slijedi, ide u ćeliju 2; i tako dalje. Sljedeći kod to ilustrira:

ako (regex_search('Najbolji prodavač knjiga danas!',m,regeks('book ((sel) (ler))')))

trošak<<m[0] <<endl;

trošak<<m[1] <<endl;

trošak<<m[2] <<endl;

trošak<<m[3] <<endl;

Izlaz je:

knjižar

prodavatelj

ćelije

čitati

Imajte na umu da grupa (prodavač) dolazi ispred grupe (sel).

Pozicija utakmice

Može se znati položaj podudaranja za svaki podniz u nizu cmatch. Odbrojavanje počinje od prvog znaka ciljnog niza, na poziciji nula. Sljedeći kod to ilustrira:

podudaranje m;

ako (regex_search('Najbolji prodavač knjiga danas!',m,regeks('book ((sel) (ler))')))

trošak<<m[0] << '->' <<m.položaj(0) <<endl;

trošak<<m[1] << '->' <<m.položaj(1) <<endl;

trošak<<m[2] << '->' <<m.položaj(2) <<endl;

trošak<<m[3] << '->' <<m.položaj(3) <<endl;

Obratite pozornost na upotrebu svojstva položaja s indeksom ćelije kao argument. Izlaz je:

knjižar->5

prodavatelj->9

ćelije->9

čitati->12

Traži i zamijeni

Nova riječ ili izraz mogu zamijeniti podudaranje. Za to se koristi funkcija regex_replace (). Međutim, ovaj put niz gdje dolazi do zamjene je objekt niza, a ne literal niza. Dakle, knjižnica nizova mora biti uključena u program. Ilustracija:

#uključi

#uključi

#uključi

koristeći imenski prostor std;

intglavni()
{
string str= »Evo, dolazi moj čovjek. Evo tvog čovjeka. ';
niz newStr=regex_replace(str,regeks('čovjek'), 'žena');
trošak<<noviStr<<endl;

povratak 0;
}

Funkcija regex_replace (), kako je ovdje kodirana, zamjenjuje sva podudaranja. Prvi argument funkcije je cilj, drugi je regex objekt, a treći zamjenski niz. Funkcija vraća novi niz, koji je cilj, ali ima zamjenu. Izlaz je:

Evo dolazi moja žena. Evo tvoje žene.

Zaključak

Regularni izraz koristi uzorke za podudaranje podnizova u nizu ciljnog niza. Uzorci imaju metakaraktere. Uobičajeno korištene funkcije za C ++ regularne izraze su: regex_search (), regex_match () i regex_replace (). Redovni izraz je uzorak u dvostrukim navodnicima. Međutim, ove funkcije uzimaju regex objekt kao argument, a ne samo regex. Regex mora biti izrađen u regex objekt da bi ga ove funkcije mogle koristiti.