A reguláris kifejezés alapjai C ++ nyelven

Regular Expression Basics C



Tekintsük a következő mondatot idézőjelben:

- Itt az emberem.

Ez a karakterlánc lehet a számítógép belsejében, és a felhasználó tudni szeretné, hogy benne van -e az ember szó. Ha benne van a férfi szó, akkor a férfi szót nőre akarja cserélni; így a karakterláncnak ezt kell olvasnia:







- Itt az asszonyom.

Sok más ilyen vágy van a számítógép -felhasználó részéről; néhány bonyolult. A rendszeres kifejezés, rövidítve, regex, a számítógép e problémák kezelésének tárgya. A C ++ egy regex nevű könyvtárat tartalmaz. Tehát a regex kezelésére szolgáló C ++ programnak a következővel kell kezdődnie:



#befoglalni

#befoglalni

névtér standard használatával;

Ez a cikk elmagyarázza a reguláris kifejezés alapjait a C ++ nyelven.



Cikk tartalma

A reguláris kifejezés alapjai

Regex

Egy olyan húr, mint itt az én emberem. a fenti a célszekvencia vagy a karakterlánc, vagy egyszerűen a cél. az ember, amit kerestünk, a reguláris kifejezés, vagy egyszerűen, regex.





Egyező

Az egyezés akkor következik be, amikor a keresett szó vagy kifejezés megtalálható. Az illesztés után cserére kerülhet sor. Például miután a férfi fent található, azt nő helyettesítheti.

Egyszerű párosítás

A következő program bemutatja, hogyan illeszkedik az ember szó.



#befoglalni

#befoglalni

névtér standard használatával;

intfő-()
{

regex reg('Férfi');
ha (regex_search(- Itt az emberem.,reg))
költség<< 'összeillő' <<endl;
más
költség<< 'nem egyezik' <<endl;

Visszatérés 0;
}

A regex_search () függvény igaz értéket ad vissza, ha van egyezés, és hamisat, ha nincs egyezés. Itt a függvény két érvet vesz fel: az első a cél karakterlánc, a második pedig a regex objektum. Maga a regex „ember”, idézőjelben. A main () függvény első utasítása képezi a regex objektumot. A regex egy típus, a reg pedig a regex objektum. A fenti program kimenete 'illeszkedik', mivel a 'man' látható a cél stringben. Ha az „ember” nem látható a célpontban, a regex_search () hamis értéket adott volna vissza, és a kimenet „nem egyezett volna”.

A következő kód kimenete nem egyezik:

regex reg('Férfi');
ha (regex_search(- Itt az én alkotásom.,reg))
költség<< 'összeillő' <<endl;
más
költség<< 'nem egyezik' <<endl;

Nem egyezik, mert a 'man' regex nem található a teljes célszalagban, 'Itt az én alkotásom'.

Minta

A szabályos kifejezés, ember fent, nagyon egyszerű. A regexek általában nem ilyen egyszerűek. A reguláris kifejezések metakarakterekkel rendelkeznek. A metakarakterek különleges jelentéssel bíró karakterek. A metakarakter a karakterekről szóló karakter. A C ++ regex metakarakterek a következők:

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

A regex, metakarakterekkel vagy anélkül, egy minta.

Karakterosztályok

Szögletes zárójelek

A minta szögletes zárójelben karaktereket tartalmazhat. Ezzel a cémsor egy adott pozíciója megfelelne a szögletes zárójelek bármelyik karakterének. Vegye figyelembe a következő célokat:

- A macska a szobában van.

- A denevér a szobában van.

- A patkány a szobában van.

A regex, [cbr] at megfelelne az első célpont macskájának. Ez ütne a második célpontban. Megfelelne a harmadik célpont patkányának. Ez azért van, mert a macska, denevér vagy patkány „c”, „b” vagy „r” betűvel kezdődik. A következő kódrészlet ezt szemlélteti:

regex reg('[cbr] at');
ha (regex_search(- A macska a szobában van.,reg))
költség<< 'összeillő' <<endl;
ha (regex_search(- A denevér a szobában van.,reg))
költség<< 'összeillő' <<endl;
ha (regex_search(- A patkány a szobában van.,reg))
költség<< 'összeillő' <<endl;

A kimenet:

illeszkedett

illeszkedett

illeszkedett

Karakterek köre

Az osztály, [cbr] a mintában [cbr], megfelelne a cél több lehetséges karakterének. Egyezne a c -vel, a b -vel vagy az r -vel a célpontban. Ha a célpontban nincs „c”, „b” vagy „r”, utána at, akkor nincs egyezés.

Bizonyos lehetőségek, például „c”, „b” vagy „r”, egy tartományban léteznek. A 0 és 9 közötti számtartománynak 10 lehetősége van, és ennek mintája [0-9]. A kisbetűs ábécé tartományának, a-tól z-ig 26 lehetősége van, és ennek mintája [a-z]. A nagybetűs tartomány, A-tól Z-ig 26 lehetőséget tartalmaz, és ennek mintája [A-Z]. - nem hivatalosan meta -karakter, de szögletes zárójelben egy tartományt jelezne. Tehát az alábbiak eredményeznek egyezést:

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

költség<< 'összeillő' <<endl;

Jegyezze meg, hogy a regex hogyan épült fel második argumentumként. Az egyezés a számjegy (6 a tartományban, 0 és 9 között) és a cél, az ID6id között található. A fenti kód egyenértékű:

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

költség<< 'összeillő' <<endl;

A következő kód egyezést eredményez:

charo[] = 'ID6iE';

ha (regex_search(o,regex('[a-z]')))

költség<< 'összeillő' <<endl;

Vegye figyelembe, hogy az első argumentum itt egy karakterlánc -változó, és nem a karakterlánc. Az egyezés az [a-z] „i” és az ID6iE „i” között van.

Ne felejtse el, hogy a tartomány egy osztály. A minta a tartománytól jobbra vagy balra lehet szöveg. A következő kód egyezést eredményez:

ha (regex_search('ID2id egy azonosító ',regex('ID [0-9] azonosító')))

költség<< 'összeillő' <<endl;

Az egyezés az ID [0-9] azonosító és az ID2id között van. A többi karakterlánc, egy azonosító, nem egyezik ebben a helyzetben.

A reguláris kifejezés alanyában (regexes) használva az osztály szó valójában halmazt jelent. Vagyis a készlet egyik karaktere egyezik.

Megjegyzés: A kötőjel - metaadat, csak szögletes zárójelben, tartományt jelezve. Ez nem metaadat a reguláris kifejezésben, a szögletes zárójeleken kívül.

Tagadás

Egy tartományt tartalmazó osztály tagadható. Vagyis a halmaz (osztály) karaktereinek nem egyeznie kell. Ezt a ^ metakarakter jelzi az osztályminta elején, közvetlenül a nyitó szögletes zárójel után. Tehát a [^0-9] azt jelenti, hogy a karakter illeszkedik a célpont megfelelő pozíciójába, amely nem lehet semmilyen karakter a 0 és 9 közötti tartományban. Tehát a következő kód nem eredményez egyezést:

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

költség<< 'összeillő' <<endl;

más

költség<< 'nem egyezik' <<endl;

A 0–9 tartományban lévő számjegy bármelyik karakterlánc -pozícióban megtalálható, 0123456789101112 ,; tehát nincs egyezés - tagadás.

A következő kód egyezést eredményez:

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

költség<< 'összeillő' <<endl;

A célpontban nem található számjegy, ABCDEFGHIJ ,; szóval van meccs.

[a-z] a [^a-z] tartományon kívüli tartomány. És így [^a-z] az [a-z] tagadása.

[A-Z] az [^A-Z] tartományon kívüli tartomány. És így [^A-Z] az [A-Z] tagadása.

Más tagadások is léteznek.

Megfelelő fehér helyek

'' Vagy t vagy r vagy n vagy f egy szóköz karakter. A következő kódban a regex, n megegyezik a cél „ n” kifejezésével:

ha (regex_search(- Az első sorból. r nA második sorból.,regex(' n')))

költség<< 'összeillő' <<endl;

Bármelyik szóköz karakterhez illő

A tetszőleges szóköz karakterhez illeszkedő minta vagy osztály: [ t r n f]. A következő kódban a „” illeszkedik:

ha (regex_search('egy kettő',regex('[ t r n f] ')))

költség<< 'összeillő' <<endl;

Bármely nem szóköz karakter illeszkedése

A nem fehér szóköz karakterhez illeszkedő minta vagy osztály: [^ t r n f]. A következő kód egyezést eredményez, mert a célban nincs szóköz:

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

költség<< 'összeillő' <<endl;

Az időszak (.) A mintában

A mintában lévő pont (.) Megegyezik a cél bármely karakterével, beleértve önmagát is, kivéve n. Egyezést a következő kóddal állítanak elő:

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

költség<< 'összeillő' <<endl;

Nincs egyező eredmény a következő kódban, mert a cél n.

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

költség<< 'összeillő' <<endl;

más

költség<< 'nem egyezik' <<endl;

Megjegyzés: A szögletes zárójelben lévő karakterosztályon belül a pontnak nincs különleges jelentése.

Egyező ismétlések

Egy karakter vagy karaktercsoport többször is előfordulhat a célstringen belül. Egy minta illeszkedhet ehhez az ismétléshez. A metakarakterek, a?, *, +És {} a cél ismétlésének megfeleltetésére szolgálnak. Ha x a karakterláncban érdekelt karakter, akkor a metakarakterek a következő jelentéssel bírnak:

x*:egyezést jelent'x' 0vagy többször,én.És.,akárhányszor

x+:egyezést jelent'x' 1vagy többször,én.És.,legalább egyszer

x? :egyezést jelent'x' 0vagy1 idő

x{n,}:egyezést jelent'x'legalább n vagy több alkalommal.jegyzeta vessző.

x{n} :mérkőzés'x'pontosan n alkalommal

x{n,m}:mérkőzés'x'legalább n alkalommal,de legfeljebb m -szer.

Ezeket a metakaraktereket ún kvantorok.

Illusztrációk

*

A * megfelel az előző karakternek vagy az előző csoportnak, nulla vagy több alkalommal. o* egyezik az „o” -val a céltárgy kutyájában. A könyvben és a megjelenésben is megfelel az oo -nak. A regex, o* megegyezik a boooo -val az Állat booooed -ban.

+

A + egy vagy több alkalommal egyezik az előző karakterrel vagy az előző csoporttal. Hasonlítsa össze nullával vagy több alkalommal *. Tehát a regex, e+ megegyezik az „e” -vel az evésben, ahol az „e” egyszer fordul elő. Az e+ megegyezik az ee -vel juhokban is, ahol az „e” többször fordul elő. Megjegyzés: az e+ nem egyezik az ásással, mert az ásásban az „e” nem fordul elő legalább egyszer.

?

Az ? megegyezik az előző karakterrel vagy az előző csoporttal, 0 vagy 1 alkalommal (és nem több). Szóval, e? egyezik az ásással, mert az „e” dig, nulla időben fordul elő. e? egyezik, mert az „e” halmazban fordul elő egyszer. Megjegyzés: e? még mindig megfelel a juhoknak; bár a juhokban két „e” van. Itt van egy árnyalat - lásd később.

{n,}

Ez megfelel az előző karakter vagy az előző csoport legalább n egymást követő ismétlésének. Tehát a regex, e {2,} egyezik a célpontban lévő két „e” -vel, a juhokkal és a három „e” -vel a célbirkában. Az e {2,} nem felel meg a halmaznak, mert a halmaznak csak egy „e” van.

{n}

Ez pontosan megegyezik az előző karakter vagy az előző csoport ismétlődő ismétléseivel. Tehát a regex, e {2} megegyezik a két „e” -vel a célban, juh. Az e {2} nem felel meg a halmaznak, mert a halmaznak csak egy „e” van. Nos, e {2} két „e” -vel egyezik a célpontban, bárány. Itt van egy árnyalat - lásd később.

{n, m}

Ez megfelel az előző karakter vagy az előző csoport több egymást követő ismétlésének, n ​​-től m -ig bárhol. Tehát az e {1,3} nem egyezik a digben, amelynek nincs „e” -je. Egyezik az „e” -vel a készletben, a két „e -vel” a juhokban, a három „e -vel” a juhban és a három „e -vel” a juhban. Az utolsó mérkőzésen van egy árnyalat - lásd később.

Megfelelő váltakozás

Tekintsük a következő cél karakterláncot a számítógépen.

A gazdaságban különböző méretű sertések vannak.

A programozó tudni szeretné, hogy ezen a célponton van -e kecske, nyúl vagy sertés. A kód a következő lenne:

charo[] = - A gazdaságban különböző méretű sertések vannak.;

ha (regex_search(o,regex('kecske | nyúl | disznó')))

költség<< 'összeillő' <<endl;

más

költség<< 'nem egyezik' <<endl;

A kód egyezést eredményez. Vegye figyelembe a váltakozó karakter, |. Lehet két, három, négy és több lehetőség is. A C ++ először megpróbálja megfeleltetni az első alternatívát, a kecskét, a cél string minden karakterhelyén. Ha kecskével nem sikerül, megpróbálja a következő alternatívát, a nyulat. Ha ez nem sikerül a nyúlnál, megpróbálja a következő alternatívát, a sertést. Ha a disznó nem sikerül, akkor a C ++ a következő pozícióba lép a célpontban, és újra az első alternatívával kezd.

A fenti kódban a disznó illeszkedik.

Kezdet vagy vég egyezése

Kezdet


Ha a ^ a regex elején van, akkor a céltárgy kezdőszövege illeszkedhet a regexhez. A következő kódban a cél kezdete abc, amely illeszkedik:

ha (regex_search('abc és def',regex('^ abc')))

költség<< 'összeillő' <<endl;

A következő kódban nincs egyezés:

ha (regex_search('Igen, abc és def',regex('^ abc')))

költség<< 'összeillő' <<endl;

más

költség<< 'nem egyezik' <<endl;

Itt az abc nincs a cél elején.

Megjegyzés: A circflex karakter, „^”, egy metakarakter a regex elején, amely megegyezik a cél karakterlánc kezdetével. Ez még mindig egy metakarakter a karakterosztály elején, ahol tagadja az osztályt.

Vége

Ha a $ a regex végén található, akkor a cémsor végszövegét illesztheti a regex. A következő kódban a cél vége xyz, amely illeszkedik:

ha (regex_search('uvw és xyz',regex('xyz $')))

költség<< 'összeillő' <<endl;

A következő kódban nincs egyezés:

ha (regex_search('uvw és xyz döntő',regex('xyz $')))

költség<< 'összeillő' <<endl;

más

költség<< 'nem egyezik' <<endl;

Itt az xyz nincs a cél végén.

Csoportosítás

Zárójelekkel karaktereket lehet mintába csoportosítani. Tekintsük a következő regexet:

'koncert (zongorista)'

A csoport itt zongorista, körülvéve a metakarakterekkel (és). Ez valójában egy alcsoport, míg egy koncert (zongorista) az egész csoport. Tekintsük a következő:

'A (zongorista jó)'

Itt az alcsoport vagy alhúr, a zongorista jó.

Alhúrok közös részekkel

A könyvelő olyan személy, aki gondoskodik a könyvekről. Képzeljünk el egy könyvtárat könyvelővel és könyvespolccal. Tegyük fel, hogy az alábbi célkarakterláncok egyike megtalálható a számítógépben:

'A könyvtárban van egy könyvespolc, amelyet csodálnak.';

'Itt a könyvelő.';

'A könyvelő a könyvespolccal dolgozik.';

Tegyük fel, hogy a programozó érdeke nem az, hogy ezek közül a mondatok közül melyik legyen a számítógépben. Ennek ellenére érdekli, hogy van -e könyvespolc vagy könyvelő a számítógépben lévő célszalagokban. Ebben az esetben a reggex a következő lehet:

'könyvespolc | könyvelő.'

A váltakozás használata.

Figyeld meg, hogy a könyv, amely mindkét szóban közös, kétszer is beírt, a minta két szavába. Annak elkerülése érdekében, hogy kétszer gépelje be a könyvet, a regexet jobb lenne így írni:

'könyv (polc | őr)'

Itt a csoport, polc | őr Az alternatív metakaraktert még mindig használták, de nem két hosszú szóra. A két hosszú szó két befejező részéhez használták. A C ++ egységként kezeli a csoportot. Tehát a C ++ olyan polcot vagy őrzőt keres, amely közvetlenül a könyv után érkezik. A következő kód kimenete illeszkedik:

charo[] = - A könyvtárban van egy könyvespolc, amelyet csodálnak.;

ha (regex_search(o,regex('könyv (polc | őr)')))

költség<< 'összeillő' <<endl;

a könyvespolc és nem a könyvelő megfelelt.

Az icase és a többsoros regex_constants

icase

Az egyezés alapértelmezés szerint megkülönbözteti a kis- és nagybetűket. A kis- és nagybetűket azonban nem lehet érzékenyíteni. Ennek eléréséhez használja a regex :: icase konstansot, a következő kód szerint:

ha (regex_search('Visszacsatolás',regex('takarmány',regex::icase)))

költség<< 'összeillő' <<endl;

A kimenet illeszkedik. Tehát az „F” nagybetűvel történő visszajelzést az „f” kisbetűs hírcsatorna illesztette össze. A regex :: icase lett a regex () konstruktor második argumentuma. Enélkül a kijelentés nem eredményezne egyezést.

Többsoros

Vegye figyelembe a következő kódot:

charo[] = '1. sor n2. sor n3. sor ';

ha (regex_search(o,regex('^. * $')))

költség<< 'összeillő' <<endl;

más

költség<< 'nem egyezik' <<endl;

A kimenet nem illeszkedik. A regex, ^.*$, Elejétől a végéig megegyezik a cél karakterlánccal. .* bármilyen karaktert jelent, n, nulla vagy több alkalommal. Tehát a cél új soros karakterei ( n) miatt nem volt egyezés.

A cél egy többsoros karakterlánc. Ahhoz, hogy a „.” Illeszkedjen az újsor karakterhez, a konstans regex :: multiline -t kell elkészíteni, ez a regex () konstrukció második argumentuma. A következő kód ezt szemlélteti:

charo[] = '1. sor n2. sor n3. sor ';

ha (regex_search(o,regex('^. * $',regex::többsoros)))

költség<< 'összeillő' <<endl;

más

költség<< 'nem egyezik' <<endl;

Egyezik a teljes cél karakterlánccal

Az új sor karakterrel ( n) nem rendelkező teljes karakterlánc illesztéséhez a regex_match () függvény használható. Ez a függvény eltér a regex_search () függvénytől. A következő kód ezt szemlélteti:

charo[] = 'első második harmadik';

ha (regex_match(o,regex('.*második.*')))

költség<< 'összeillő' <<endl;

Itt meccs van. Ne feledje azonban, hogy a regex illeszkedik a teljes cémsorhoz, és a cél karakterláncban nincs „ n”.

A match_results objektum

A regex_search () függvény argumentumokat vehet fel a cél és a regex objektum között. Ez az argumentum a match_results objektum. Az egész illesztett (rész) karakterlánc és az illesztett alhúrok megismerhetők vele. Ez az objektum egy speciális tömb metódusokkal. A match_results objektumtípus a cmatch (karakterlánc -literálok esetén).

Egyezések megszerzése

Vegye figyelembe a következő kódot:

charo[] = - A nő, akit keresett!;

cmatch m;

ha (regex_search(o,m,regex('w.m.n')))

költség<<m[0] <<endl;

A cél karakterláncban a nő szó szerepel. A kimenet nő ’, ami megfelel a regexnek, w.m.n. A nulla indexnél a speciális tömb tartja az egyetlen egyezést, ami a nő.

Az osztálybeállításoknál csak a célban talált első karakterlánc kerül elküldésre a speciális tömbhöz. A következő kód ezt szemlélteti:

cmatch m;

ha (regex_search(- A patkány, a macska, a denevér!,m,regex('[bcr] itt:')))

költség<<m[0] <<endl;

költség<<m[1] <<endl;

költség<<m[2] <<endl;

A kimenet patkány az index nullától. m [1] és m [2] üres.

Alternatívák esetén csak a célban talált első karakterlánc kerül elküldésre a speciális tömbhöz. A következő kód ezt szemlélteti:

ha (regex_search(- A nyúl, a kecske, a disznó!,m,regex('kecske | nyúl | disznó')))

költség<<m[0] <<endl;

költség<<m[1] <<endl;

költség<<m[2] <<endl;

A kimenet nyúl index nullától. m [1] és m [2] üres.

Csoportosítások

Csoportok bevonásakor a teljes minta illeszkedik a speciális tömb nulla cellájába. A következő talált karakterlánc az 1. cellába kerül; a következő karakterlánc a 2. cellába kerül; stb. A következő kód ezt szemlélteti:

ha (regex_search('A mai legjobb könyvkereskedő!',m,regex('könyv ((sel) (ler))')))

költség<<m[0] <<endl;

költség<<m[1] <<endl;

költség<<m[2] <<endl;

költség<<m[3] <<endl;

A kimenet:

könyvkereskedő

eladó

sejt

olvas

Vegye figyelembe, hogy a csoport (eladó) a csoport (sel) elé kerül.

A mérkőzés helye

Ismert a cmatch tömb minden alláncának egyezése. A számlálás a cémsor első karakterétől kezdődik, a nulla pozícióban. A következő kód ezt szemlélteti:

cmatch m;

ha (regex_search('A mai legjobb könyvkereskedő!',m,regex('könyv ((sel) (ler))')))

költség<<m[0] << '->' <<m.pozíció(0) <<endl;

költség<<m[1] << '->' <<m.pozíció(1) <<endl;

költség<<m[2] << '->' <<m.pozíció(2) <<endl;

költség<<m[3] << '->' <<m.pozíció(3) <<endl;

Vegye figyelembe a pozíció tulajdonság használatát a cellaindex mellett argumentumként. A kimenet:

könyvkereskedő->5

eladó->9

sejt->9

olvas->12

Keresés és csere

Egy új szó vagy kifejezés helyettesítheti a mérkőzést. Erre a regex_replace () függvény szolgál. Ezúttal azonban a karakterlánc, ahol a csere történik, a karakterlánc objektum, nem pedig a literál. Tehát a string könyvtárat be kell vonni a programba. Ábra:

#befoglalni

#befoglalni

#befoglalni

névtér standard használatával;

intfő-()
{
string str= - Tessék, jön az emberem. Ott az embere.;
karakterlánc newStr=regex_replace(o,regex('Férfi'), 'nő');
költség<<newStr<<endl;

Visszatérés 0;
}

Az itt kódolt regex_replace () függvény helyettesíti az összes egyezést. A függvény első argumentuma a cél, a második a regex objektum, a harmadik pedig a helyettesítő karakterlánc. A függvény új karakterláncot ad vissza, amely a cél, de rendelkezik a cserével. A kimenet:

Itt jön az asszonyom. Ott megy az asszonyod.

Következtetés

A reguláris kifejezés mintákat használ a célszekvencia -karakterláncban lévő alláncok illesztéséhez. A minták metakarakterekkel rendelkeznek. A C ++ reguláris kifejezések általánosan használt funkciói a következők: regex_search (), regex_match () és regex_replace (). A regex egy minta idézőjelben. Ezek a függvények azonban a regex objektumot argumentumnak veszik, és nem csak a regexet. A regexet regex objektummá kell tenni, mielőtt ezek a függvények használni tudnák.