Grundläggande uttryck i C ++

Regular Expression Basics C



Tänk på följande mening i citattecken:

'Här är min man.'

Den här strängen kan vara inne i datorn, och användaren kanske vill veta om den har ordet man. Om det har ordet man, kan han då vilja ändra ordet man till kvinna; så att strängen ska läsa:







'Här är min kvinna.'

Det finns många andra önskningar som dessa från datoranvändaren; vissa är komplexa. Regular Expression, förkortat, regex, är föremål för att hantera dessa problem av datorn. C ++ kommer med ett bibliotek som heter regex. Så ett C ++ - program för att hantera regex bör börja med:



#omfatta

#omfatta

med namnutrymme std;

Den här artikeln förklarar grundläggande uttryck i C ++.



Artikelinnehåll

Regelbundna uttrycksgrunder

Regex

En sträng som här är min man. ovan är målsekvensen eller målsträngen eller helt enkelt mål. man, som man sökte efter, är det reguljära uttrycket, eller helt enkelt, regex.





Motsvarande

Matchning sägs inträffa när ordet eller frasen som man söker efter finns. Efter matchning kan en ersättning ske. Till exempel, efter att mannen är placerad ovan, kan den ersättas av en kvinna.

Enkel matchning

Följande program visar hur ordet man matchas.



#omfatta

#omfatta

med namnutrymme std;

inthuvud()
{

regex reg('man');
om (regex_search('Här är min man.',reg))
kosta<< 'matchade' <<endl;
annan
kosta<< 'matchas inte' <<endl;

lämna tillbaka 0;
}

Funktionen regex_search () returnerar true om det finns en matchning och returnerar false om ingen matchning inträffar. Här tar funktionen två argument: den första är målsträngen och den andra är regex -objektet. Regexen i sig är 'man', i dubbla citattecken. Det första uttalandet i huvudfunktionen () bildar regex -objektet. Regex är en typ, och reg är regex -objektet. Ovanstående programmets utmatning är 'matchad', eftersom 'man' ses i målsträngen. Om 'man' inte sågs i målet skulle regex_search () ha returnerat falskt och utmatningen skulle ha 'inte matchats'.

Utdata från följande kod matchas inte:

regex reg('man');
om (regex_search('' Här är min skapelse. '',reg))
kosta<< 'matchade' <<endl;
annan
kosta<< 'matchas inte' <<endl;

Matchas inte eftersom regex 'man' inte kunde hittas i hela målsträngen, 'Här är min skapelse'.

Mönster

Det vanliga uttrycket, mannen ovan, är väldigt enkelt. Regexes är vanligtvis inte så enkla. Regelbundna uttryck har metatecken. Metatecken är tecken med speciella betydelser. En metakaraktär är ett tecken om karaktärer. C ++ regex -metatecken är:

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

En regex, med eller utan metatecken, är ett mönster.

Teckenklasser

Hakparentes

Ett mönster kan ha tecken inom hakparenteser. Med detta skulle en viss position i målsträngen matcha någon av hakparentesernas tecken. Tänk på följande mål:

'Katten är i rummet.'

'Fladdermusen är i rummet.'

'Råttan är i rummet.'

Regexen, [cbr] på skulle matcha katt i det första målet. Det skulle matcha fladdermus i det andra målet. Det skulle matcha råtta i det tredje målet. Detta beror på att katt eller fladdermus eller råtta börjar med 'c' eller 'b' eller 'r'. Följande kodsegment illustrerar detta:

regex reg('[cbr] på');
om (regex_search('Katten är i rummet.',reg))
kosta<< 'matchade' <<endl;
om (regex_search('Fladdermusen är i rummet.',reg))
kosta<< 'matchade' <<endl;
om (regex_search('Råttan är i rummet.',reg))
kosta<< 'matchade' <<endl;

Utgången är:

matchade

matchade

matchade

Utbud av tecken

Klassen, [cbr] i mönstret [cbr], skulle matcha flera möjliga tecken i målet. Det skulle matcha 'c' eller 'b' eller 'r' i målet. Om målet inte har något av 'c' eller 'b' eller 'r', följt av kl, skulle det inte finnas någon matchning.

Vissa möjligheter som 'c' eller 'b' eller 'r' finns inom ett område. Räckvidden av siffror, 0 till 9 har 10 möjligheter, och mönstret för det är [0-9]. Utbudet av små alfabet, a till z, har 26 möjligheter, och mönstret för det är [a-z]. Utbudet av stora alfabet, A till Ö, har 26 möjligheter, och mönstret för det är [A-Z]. - är inte officiellt en metakaraktär, men inom hakparenteser skulle det indikera ett intervall. Så, följande ger en matchning:

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

kosta<< 'matchade' <<endl;

Notera hur regex har konstruerats som det andra argumentet. Matchningen sker mellan siffran, 6 i intervallet, 0 till 9, och 6: an i målet, ID6id. Ovanstående kod motsvarar:

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

kosta<< 'matchade' <<endl;

Följande kod ger en matchning:

rödingsid[] = 'ID6iE';

om (regex_search(sid,regex('[a-z]')))

kosta<< 'matchade' <<endl;

Observera att det första argumentet här är en strängvariabel och inte strängen bokstavlig. Matchen är mellan 'i' i [a-z] och 'i' i ID6iE.

Glöm inte att en räckvidd är en klass. Det kan finnas text till höger om intervallet eller till vänster om intervallet i mönstret. Följande kod ger en matchning:

om (regex_search('ID2id är ett ID ',regex('ID [0-9] id')))

kosta<< 'matchade' <<endl;

Matchen är mellan ID [0-9] id och ID2id. Resten av målsträngen, är ett ID, matchas inte i den här situationen.

Som det används i det reguljära uttrycksämnet (regexes) betyder ordklassen faktiskt en uppsättning. Det vill säga att en av karaktärerna i uppsättningen är att matcha.

Obs: bindestreck - är en metatecken endast inom hakparenteser, vilket indikerar ett intervall. Det är inte en metakaraktär i regexet, utanför hakparenteserna.

Negation

En klass med ett intervall kan förnekas. Det vill säga att ingen av tecknen i uppsättningen (klassen) ska matcha. Detta indikeras med metatecknet ^ i början av klassmönstret, strax efter den öppnande hakparentesen. Så, [^0-9] betyder att matcha tecknet på lämplig position i målet, vilket inte är något tecken i intervallet, 0 till 9 inklusive. Så följande kod kommer inte att producera en matchning:

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

kosta<< 'matchade' <<endl;

annan

kosta<< 'matchas inte' <<endl;

En siffra inom intervallet 0 till 9 kunde hittas i någon av målsträngpositionerna, 0123456789101112 ,; så det finns ingen match - negation.

Följande kod ger en matchning:

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

kosta<< 'matchade' <<endl;

Ingen siffra kunde hittas i målet, ABCDEFGHIJ ,; så det finns en match.

[a-z] är ett område utanför [^a-z]. Och så är [^a-z] negationen av [a-z].

[A-Z] är ett område utanför [^A-Z]. Och så är [^A-Z] negationen av [A-Z].

Andra negationer finns.

Matchande blanksteg

‘’ Eller t eller r eller n eller f är ett blanksteg. I följande kod matchar regex, n ‘ n’ i målet:

om (regex_search('Av rad ett. r nAv rad två. ',regex(' n')))

kosta<< 'matchade' <<endl;

Matchar alla Whitespace -karaktärer

Mönstret eller klassen som matchar ett vitt mellanslagstecken är [ t r n f]. I följande kod matchas ‘’:

om (regex_search('ett två',regex('[ t r n f] ')))

kosta<< 'matchade' <<endl;

Matchar alla icke-whitespace-karaktärer

Mönstret eller klassen som matchar alla icke-vita mellanslagstecken är [^ t r n f]. Följande kod producerar en matchning eftersom det inte finns någon blanksteg i målet:

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

kosta<< 'matchade' <<endl;

Perioden (.) I mönstret

Perioden (.) I mönstret matchar alla tecken inklusive sig själv, utom n, i målet. En matchning produceras i följande kod:

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

kosta<< 'matchade' <<endl;

Inga matchningar resulterar i följande kod eftersom målet är n.

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

kosta<< 'matchade' <<endl;

annan

kosta<< 'matchas inte' <<endl;

Obs! Inuti en teckenklass med hakparenteser har perioden ingen speciell betydelse.

Matchande upprepningar

Ett tecken eller en grupp tecken kan förekomma mer än en gång inom målsträngen. Ett mönster kan matcha denna upprepning. Metatecknen,?, *, +Och {} används för att matcha upprepningen i målet. Om x är ett tecken av intresse i målsträngen har metatecknen följande betydelser:

x*:betyder match'x' 0eller fler gånger,i.Och.,hur många gånger som helst

x+:betyder match'x' 1eller fler gånger,i.Och.,åtminstone en gång

x? :betyder match'x' 0eller1 tid

x{n,}:betyder match'x'åtminstone n eller fler gånger.Noterakomma.

x{n} :match'x'exakt n gånger

x{n,m}:match'x'minst n gånger,men inte mer än m gånger.

Dessa metatecken kallas kvantifierare.

Illustrationer

*

* Matchar föregående tecken eller föregående grupp, noll eller fler gånger. o* matchar ‘o’ i hund i målsträngen. Det matchar också oo i bok och tittar. Regexen, o* matchar boooo i The animal booooed .. Obs: o* matches dig, där ‘o’ inträffar noll (eller mer) tid.

+

+ Matchar föregående tecken eller föregående grupp, 1 eller flera gånger. Kontrast det med noll eller fler gånger för *. Så regex, e+ matchar ‘e’ i äta, där ‘e’ förekommer en gång. e+ matchar också ee hos får, där ‘e’ förekommer mer än en gång. Obs! E+ kommer inte att matcha dig eftersom i dig förekommer 'e' inte minst en gång.

?

Den? matchar föregående tecken eller föregående grupp, 0 eller 1 gång (och inte mer). Så, e? matchningar gräver eftersom 'e' förekommer i grävning, nolltid. e? matchar inställda eftersom 'e' förekommer i set, en gång. Obs: e? matchar fortfarande får; även om det finns två e i får. Det finns en nyans här - se senare.

{n,}

Detta matchar minst n på varandra följande repetitioner av ett föregående tecken eller föregående grupp. Så regexen, e {2,} matchar de två ’e: erna i målet, fåren och de tre’ e: n i målfåren. e {2,} matchar inte uppsättningen, eftersom uppsättningen bara har ett 'e'.

{n}

Detta matchar exakt n på varandra följande repetitioner av ett föregående tecken eller föregående grupp. Så regex, e {2} matchar de två ’e’erna i målet, får. e {2} matchar inte uppsättningen eftersom uppsättningen bara har ett e. Tja, e {2} matchar två e i målet, tjej. Det finns en nyans här - se senare.

{n, m}

Detta matchar flera på varandra följande repetitioner av en föregående karaktär eller föregående grupp, var som helst från n till m, inklusive. Så e {1,3} matchar ingenting i dig, som inte har något 'e'. Den matchar den ena 'e' i uppsättningen, de två 'e'en i får, de tre' e'en i fåren och tre 'e'en i sheeeep. Det finns en nyans vid förra matchen - se senare.

Matchande alternativ

Tänk på följande målsträng i datorn.

Gården har grisar i olika storlekar.

Programmeraren kanske vill veta om detta mål har get eller kanin eller gris. Koden skulle vara följande:

rödingsid[] = 'Gården har grisar i olika storlekar.';

om (regex_search(sid,regex('get | kanin | gris')))

kosta<< 'matchade' <<endl;

annan

kosta<< 'matchas inte' <<endl;

Koden ger en matchning. Observera användningen av växlingstecknet |. Det kan finnas två, tre, fyra och fler alternativ. C ++ försöker först matcha det första alternativet, get, vid varje teckenposition i målsträngen. Om det inte lyckas med get, försöker det nästa alternativ, kanin. Om det inte lyckas med kanin försöker det nästa alternativ, gris. Om grisen misslyckas går C ++ vidare till nästa position i målet och börjar med det första alternativet igen.

I koden ovan matchas gris.

Matchande början eller slut

Början


Om ^ är i början av regexet kan starttexten för målsträngen matchas av regexet. I följande kod är starten på målet abc, som matchas:

om (regex_search('abc och def',regex('^ abc')))

kosta<< 'matchade' <<endl;

Ingen matchning sker i följande kod:

om (regex_search('Ja, abc och def',regex('^ abc')))

kosta<< 'matchade' <<endl;

annan

kosta<< 'matchas inte' <<endl;

Här är abc inte i början av målet.

Obs! Cirkumflex -tecknet ‘^’ är en metatecken i början av regexet som matchar målsträngens början. Det är fortfarande en metakaraktär i början av teckenklassen, där den förnekar klassen.

Slutet

Om $ är i slutet av regexet kan sluttexten för målsträngen matchas av regexet. I följande kod är slutet på målet xyz, som matchas:

om (regex_search('uvw och xyz',regex('xyz $')))

kosta<< 'matchade' <<endl;

Ingen matchning sker i följande kod:

om (regex_search('uvw och xyz final',regex('xyz $')))

kosta<< 'matchade' <<endl;

annan

kosta<< 'matchas inte' <<endl;

Här är xyz inte i slutet av målet.

Gruppering

Parenteser kan användas för att gruppera tecken i ett mönster. Tänk på följande regex:

'en konsert (pianist)'

Gruppen här är pianist omgiven av metatecknen (och). Det är faktiskt en undergrupp, medan en konsert (pianist) är hela gruppen. Tänk på följande:

'(Pianisten är bra)'

Här är undergruppen eller understrängen, pianisten är bra.

Delsträngar med gemensamma delar

En bokhållare är en person som tar hand om böcker. Tänk dig ett bibliotek med en bokhållare och bokhylla. Antag att en av följande målsträngar finns i datorn:

'Biblioteket har en bokhylla som beundras.';

'Här är bokhållaren.';

'Bokhållaren arbetar med bokhyllan.';

Antag att programmerarens intresse inte är att veta vilken av dessa meningar som finns i datorn. Ändå är hans intresse att veta om bokhylla eller bokhållare finns i vilken målsträng som helst i datorn. I detta fall kan hans regex vara:

'bokhylla | bokhållare.'

Använda växel.

Lägg märke till att boken, som är gemensam för båda orden, har skrivits två gånger, i de två orden i mönstret. För att undvika att skriva bok två gånger skulle regexet vara bättre skrivet som:

'bok (hylla | förvarare)'

Här, gruppen, hylla | keeper Alternativet metakaraktär har fortfarande använts, men inte för två långa ord. Den har använts för de två slutdelarna av de två långa orden. C ++ behandlar en grupp som en enhet. Så, C ++ kommer att leta efter hylla eller behållare som kommer direkt efter boken. Utdata från följande kod matchas:

rödingsid[] = 'Biblioteket har en bokhylla som beundras.';

om (regex_search(sid,regex('bok (hylla | förvarare)')))

kosta<< 'matchade' <<endl;

bokhylla och inte bokhållare har matchats.

Icase och multiline regex_constants

icase

Matchning är skiftlägeskänslig som standard. Det kan dock göras skiftlägeskänsligt. För att uppnå detta, använd regex :: icase -konstanten, som i följande kod:

om (regex_search('Respons',regex('utfodra',regex::icase)))

kosta<< 'matchade' <<endl;

Utgången matchas. Så Feedback med stora F har matchats med foder med gemener f. regex :: icase har gjorts till regex () -konstruktörens andra argument. Utan det skulle uttalandet inte ge någon matchning.

Multiline

Tänk på följande kod:

rödingsid[] = 'linje 1 nlinje 2 nrad 3 ';

om (regex_search(sid,regex('^. * $')))

kosta<< 'matchade' <<endl;

annan

kosta<< 'matchas inte' <<endl;

Utgången matchas inte. Regexen, ^.*$, Matchar målsträngen från början till slutet. .* betyder alla tecken utom n, noll eller fler gånger. Så på grund av nyradstecknen ( n) i målet var det ingen matchning.

Målet är en rad med flera linjer. För att '.' Ska matcha nylinjetecknet måste konstant regex :: multiline göras, det andra argumentet för regex () -konstruktionen. Följande kod illustrerar detta:

rödingsid[] = 'linje 1 nlinje 2 nrad 3 ';

om (regex_search(sid,regex('^. * $',regex::multiline)))

kosta<< 'matchade' <<endl;

annan

kosta<< 'matchas inte' <<endl;

Matcha hela målsträngen

För att matcha hela målsträngen, som inte har newline -tecknet ( n), kan funktionen regex_match () användas. Denna funktion skiljer sig från regex_search (). Följande kod illustrerar detta:

rödingsid[] = 'första andra tredje';

om (regex_match(sid,regex('.*andra.*')))

kosta<< 'matchade' <<endl;

Det finns en match här. Observera dock att regexet matchar hela målsträngen och att målsträngen inte har någon ‘ n’.

Match_results -objektet

Regex_search () -funktionen kan ta ett argument mellan målet och regex-objektet. Detta argument är match_results -objektet. Hela matchade (del) strängen och understrängarna som matchas kan kännas med den. Detta objekt är en speciell array med metoder. Objekttypen match_results är cmatch (för stränglitteraler).

Skaffa matcher

Tänk på följande kod:

rödingsid[] = 'Kvinnan du letade efter!';

cmatch m;

om (regex_search(sid,m,regex('w.m.n')))

kosta<<m[0] <<endl;

Målsträngen har ordet kvinna. Utgången är kvinna ’, vilket motsvarar regexet, w.m.n. Vid index noll håller specialmatrisen den enda matchningen, vilket är kvinna.

Med klassalternativ skickas endast den första delsträngen som finns i målet till den särskilda matrisen. Följande kod illustrerar detta:

cmatch m;

om (regex_search('Råttan, katten, fladdermusen!',m,regex('[bcr] på')))

kosta<<m[0] <<endl;

kosta<<m[1] <<endl;

kosta<<m[2] <<endl;

Utgången är råtta från index noll. m [1] och m [2] är tomma.

Med alternativ skickas endast den första delsträngen som finns i målet till den särskilda matrisen. Följande kod illustrerar detta:

om (regex_search('Kaninen, geten, grisen!',m,regex('get | kanin | gris')))

kosta<<m[0] <<endl;

kosta<<m[1] <<endl;

kosta<<m[2] <<endl;

Utdata är kanin från index noll. m [1] och m [2] är tomma.

Grupperingar

När grupper är inblandade går det fullständiga mönstret in i cellnoll i den speciella matrisen. Nästa delsträng som hittas går in i cell 1; understrängen som följer, går in i cell 2; och så vidare. Följande kod illustrerar detta:

om (regex_search('Bästa bokhandlare idag!',m,regex('bok ((sel) (ler))')))

kosta<<m[0] <<endl;

kosta<<m[1] <<endl;

kosta<<m[2] <<endl;

kosta<<m[3] <<endl;

Utgången är:

bokhandlare

säljare

cell

läsa

Observera att gruppen (säljaren) kommer före gruppen (sel).

Matchens position

Matchningspositionen för varje delsträng i cmatch-arrayen kan vara känd. Räkningen börjar från det första tecknet i målsträngen, vid position noll. Följande kod illustrerar detta:

cmatch m;

om (regex_search('Bästa bokhandlare idag!',m,regex('bok ((sel) (ler))')))

kosta<<m[0] << '->' <<m.placera(0) <<endl;

kosta<<m[1] << '->' <<m.placera(1) <<endl;

kosta<<m[2] << '->' <<m.placera(2) <<endl;

kosta<<m[3] << '->' <<m.placera(3) <<endl;

Notera användningen av positionsegenskapen, med cellindex, som ett argument. Utgången är:

bokhandlare->5

säljare->9

cell->9

läsa->12

Sök och ersätt

Ett nytt ord eller en fras kan ersätta matchningen. Regex_replace () -funktionen används för detta. Men den här gången är strängen där ersättningen sker strängobjektet, inte strängen bokstavlig. Så strängbiblioteket måste inkluderas i programmet. Illustration:

#omfatta

#omfatta

#omfatta

med namnutrymme std;

inthuvud()
{
sträng str= 'Här kommer min man. Där går din man. ';
sträng newStr=regex_replace(sid,regex('man'), 'kvinna');
kosta<<newStr<<endl;

lämna tillbaka 0;
}

Funktionen regex_replace (), som kodad här, ersätter alla matchningar. Funktionens första argument är målet, det andra är regex -objektet och det tredje är ersättningssträngen. Funktionen returnerar en ny sträng, som är målet men har ersättningen. Utgången är:

Här kommer min kvinna. Där går din kvinna.

Slutsats

Det reguljära uttrycket använder mönster för att matcha substreringar i målsekvenssträngen. Mönster har metatecken. Vanliga funktioner för C ++ reguljära uttryck är: regex_search (), regex_match () och regex_replace (). En regex är ett mönster i dubbla citattecken. Dessa funktioner tar emellertid regex -objektet som ett argument och inte bara regexet. Regexet måste göras till ett regex -objekt innan dessa funktioner kan använda det.