Lehet, hogy ez a karakterlánc a számítógép belsejében található, és a felhasználó tudni szeretné, hogy van-e rajta „ember” szó. Ha benne van a férfi szó, akkor a „férfi” szót „nőre” akarja változtatni; hogy a karakterlánc a következő legyen:
"Itt van a nőm."Számos ilyen vágy van még a számítógép-használótól; némelyik összetett. A reguláris kifejezés, rövidítve, a regex, a számítógép kezeli ezeket a problémákat. A C ++ egy regex nevű könyvtárral érkezik. Tehát a regex kezelésére szolgáló C ++ programnak a következőkkel kell kezdődnie:
#include#include
névtér használata std;
Ez a cikk elmagyarázza a C reguláris kifejezés alapjait++.
A cikk tartalma
- A reguláris kifejezés alapjai
- Minta
- Karakterosztályok
- A szóközök egyezése
- A periódus (.) a Mintában
- Ismétlések egyeztetése
- Megfelelő váltakozás
- Egyezés kezdete vagy vége
- Csoportosítás
- Az ikáz és a többsoros regex_konstansok
- Az egész cél elérése
- A match_results objektum
- A mérkőzés helyzete
- Keresés és csere
- Következtetés
A reguláris kifejezés alapjai
Regex
Olyan húr, mint „Itt az emberem.A fenti ”a célsorozat vagy a céllánc, vagy egyszerűen a cél. Az „ember”, amelyet kerestek, a reguláris kifejezés, vagy egyszerűen csak a regex kifejezés.
Egyezés
Az egyeztetés akkor fordul elő, ha a keresett szó vagy kifejezés megtalálható. Az egyeztetés után cserére kerülhet sor. Például, miután a „férfi” fent található, helyébe „nő” léphet.
Egyszerű illesztés
A következő program megmutatja, hogy hogyan illeszkedik az „ember” szó.
#include#include
névtér használata std;
int main ()
regex reg ("ember");
if (regex_search ("Itt van az emberem.", reg))
cout << "matched" << endl;
más
cout << "not matched" << endl;
visszatér 0;
A regex_search () függvény true-t ad vissza, ha van egyezés, és false-t ad vissza, ha nem történik egyezés. Itt a függvénynek két argumentuma van: az első a cél karaktersorozat, a második a regex objektum. Maga a regex "ember", dupla idézőjelben. A main () függvény első állítása alkotja a regex objektumot. A Regex egy típus, a reg pedig a regex objektum. A fenti program kimenete "egyezik", mivel a "man" látható a cél karaktersorozatban. Ha az "ember" nem látható a célban, akkor a regex_search () hamis értéket adott volna vissza, és a kimenet "nem egyeztetne".
A következő kód kimenete „nem egyezik”:
regex reg ("ember");if (regex_search ("Itt van az én készítésem.", reg))
cout << "matched" << endl;
más
cout << "not matched" << endl;
Nem egyezik, mert a regex "man" nem található a teljes célsztringben: "Itt van az én készítésem."
Minta
A fenti „ember” reguláris kifejezés 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 mintának szögletes zárójelben lehetnek karakterei. Ezzel a cél karaktersorozat egy bizonyos helyzete megegyezik a szögletes zárójelben szereplő karakterekkel. Vegye figyelembe a következő célokat:
"A macska a szobában van.""Az ütő a szobában van."
"A patkány a szobában van."
A regex, [cbr] at, megegyezik a macskával az első célpontban. Megfelelne a denevérnek a második célpontban. Megtalálná a patkányt a harmadik célpontban. Ennek oka, hogy a „macska”, a „denevér” vagy a „patkány” „c” vagy „b” vagy „r” betűvel kezdődik. A következő kódszegmens ezt szemlélteti:
regex reg ("[cbr] at");if (regex_search ("A macska a szobában van.", reg))
cout << "matched" << endl;
if (regex_search ("Az ütő a szobában van.", reg))
cout << "matched" << endl;
if (regex_search ("A patkány a szobában van.", reg))
cout << "matched" << endl;
A kimenet:
egyeztetettegyeztetett
egyeztetett
Karakterek köre
Az osztály, a [cbr] a [cbr] mintában, több lehetséges karaktert illeszt a célba. Megfelelne a célban a „c”, „b” vagy „r” betűnek. Ha a célpontban nincs „c”, „b” vagy „r”, majd „at”, akkor nem lesz egyezés.
Néhány lehetőség, például a „c”, „b” vagy „r”, létezik egy tartományban. A 0 és 9 közötti számjegytartománynak 10 lehetősége van, és ennek mintája [0-9]. A kisbetűk tartománya, az a – z, 26 lehetőséggel rendelkezik, és ennek mintája [a-z]. A nagybetűk tartománya, A-tól Z-ig, 26 lehetőséggel rendelkezik, és ennek mintája [A-Z]. - hivatalosan nem metakarakter, de szögletes zárójelben egy tartományt jelöl. Tehát a következő eredményez egyezést:
if (regex_search ("ID6id", regex ("[0-9]")))cout << "matched" << endl;
Vegye figyelembe, hogy a regexet hogyan építették fel második argumentumként. Az egyezés a számjegy, a tartomány 6, 0 és 9 között, és a cél 6 között található, „ID6id”. A fenti kód megegyezik:
if (regex_search ("ID6id", regex ("[0123456789]")))cout << "matched" << endl;
A következő kód egyezést eredményez:
char str [] = "ID6iE";if (regex_search (str, regex ("[a-z]")))
cout << "matched" << endl;
Vegye figyelembe, hogy az első argumentum egy string változó, és nem a string literal. A mérkőzés „i” a [a-z] -ben és „i” között van az „ID6iE” -ben.
Ne felejtsük el, hogy a tartomány egy osztály. A mintában a tartománytól jobbra vagy a tartománytól balra lehet szöveg. A következő kód egyezést eredményez:
if (regex_search ("ID2id egy ID ", regex (" ID [0-9] id ")))cout << "matched" << endl;
Az egyezés az „ID [0-9] id” és az „ID2id” között van. A cél karaktersorozat többi része, „egy azonosító”, nem egyezik ebben a helyzetben.
A reguláris kifejezés alatt (regexes) az osztály szó valójában halmazt jelent. Vagyis a készletben szereplő karakterek egyeznek.
Megjegyzés: A kötőjel - csak szögletes zárójelben lévő metakarakter, amely egy tartományt jelöl. Ez nem metakarakter a regexben, a szögletes zárójelben kívül.
Tagadás
Egy osztály, amely egy tartományt tartalmaz, tagadható. Vagyis a halmaz (osztály) karaktereinek nem egyeznek meg. Ezt az osztályminta elején, közvetlenül a nyitó szögletes zárójel után a ^ metakarakter jelzi. Tehát a [^ 0-9] azt jelenti, hogy a karakter illeszkedik a cél megfelelő pozíciójába, amely nem egy karakter a 0–9 közötti tartományban. Tehát a következő kód nem eredményez egyezést:
if (regex_search ("0123456789101112", regex ("[^ 0-9]")))cout << "matched" << endl;
más
cout << "not matched" << endl;
A 0 és 9 közötti számjegy található a célhúrok bármelyik pozíciójában, „0123456789101112”; tehát nincs egyezés - tagadás.
A következő kód egyezést eredményez:
if (regex_search ("ABCDEFGHIJ", regex ("[^ 0-9]")))cout << "matched" << endl;
Nem található számjegy a célpontban, „ABCDEFGHIJ”; szóval van meccs.
[a-z] egy tartomány, amely kívül esik [^ a-z]. Tehát [^ a-z] az [a-z] tagadása.
[A-Z] egy tartomány, amely kívül esik [^ A-Z]. Tehát [^ A-Z] az [A-Z] tagadása.
Más negációk léteznek.
A szóközök egyezése
"vagy \ t vagy \ r vagy \ n vagy \ f egy szóköz karakter. A következő kódban a „\ n” regex, a „\ n” kifejezés megegyezik a célban:
if (regex_search ("Az első sorból.\ r \ nKettő sorból.", regex (" \ n ")))cout << "matched" << endl;
Bármely Whitespace karakter illesztése
A minta vagy osztály, amely megfelel bármely szóköz karakternek, a következő: [\ t \ r \ n \ f]. A következő kódban a "egyezik:
if (regex_search ("egy kettő", regex ("[\ t \ r \ n \ f]")))cout << "matched" << endl;
Bármely nem fehér szóköz karakter beillesztése
A nem fehér szóköz karaktereinek megfelelő minta vagy osztály: [^ \ t \ r \ n \ f]. A következő kód egyezést eredményez, mert a szóközben nincs szóköz:
if (regex_search ("1234abcd", regex ("[^ \ t \ r \ n \ f]")))cout << "matched" << endl;
A periódus (.) a Mintában
A periódus (.) a mintában minden karakter megegyezik, beleértve önmagát is, a \ n kivételével a célban. A mérkőzés a következő kóddal készül:
if (regex_search ("1234abcd", regex (".")))cout << "matched" << endl;
Nincs megfelelő találat a következő kódban, mert a cél „\ n”.
if (regex_search ("\ n", regex (".")))cout << "matched" << endl;
más
cout << "not matched" << endl;
Megjegyzés: A szögletes zárójeles karakterosztályban a periódusnak nincs különösebb jelentése.
Ismétlések egyeztetése
Egy karakter vagy karaktercsoport többször is előfordulhat a cél karaktersorozaton belül. Egy minta megfelel ennek az ismétlésnek. A metakarakterek, ?, A *, + és a karakterek a cél ismétlésének megfelelővé tételére szolgálnak. Ha x az érdeklődő karakter a célláncban, akkor a metakarakterek a következő jelentéssel bírnak:
x *: az 'x' 0 vagy többszörös egyezést jelenti, azaz.e., akárhányszorx +: az 'x' egy vagy többszörös egyezést jelenti, azaz.e., legalább egyszer
x? : azt jelenti, hogy az „x” mérkőzés 0 vagy 1 alkalommal van
x n,: legalább n vagy többször megfelel az 'x' kifejezésnek. Vegye figyelembe a vesszőt.
x n: pontosan n -szer egyezzen az 'x'-lel
x n, m: legalább n-szer, de legfeljebb m-szer egyezzen az 'x'-vel.
Ezeket a metakaraktereket kvantoroknak nevezzük.
Illusztrációk
*
A * nulla vagy többször megegyezik az előző karakterrel vagy az előző csoporttal. Az „o *” megegyezik az o-val a cél karakterlánc „kutyájában”. A „könyvben” és a „kinézetben” is megfelel az „oo” szónak. A regex, az „o *” megegyezik a „boooo” szóval az „Az állat booooed.”. Megjegyzés: Az „o *” megfelel a „dig” szónak, ahol az „o” nulla (vagy annál több) idővel fordul elő.
+
A + egy vagy többször megegyezik az előző karakterrel vagy az előző csoporttal. Kontrasztja nullával vagy többször a *. Tehát a regex, az „e +” egyezik az „e” szóval az „enni” mezőben, ahol az „e” egyszer előfordul. Az „e +” megfelel az „ee” kifejezésnek a „juhokban” is, ahol az „e” többször fordul elő. Megjegyzés: Az „e +” nem fog egyezni a „dig” szóval, mert az „dig” -ban az „e” nem fordul elő legalább egyszer.
?
A ? megfelel az előző karakternek vagy az előző csoportnak, 0 vagy 1 alkalommal (és nem több). Tehát: „e?”Egyezik a„ dig ”-nel, mert az„ e ”nulla időben„ dig ”-ben fordul elő. „E?”Megfelel a„ set ”-nek, mert az„ e ”egyszer szerepel a“ set ”-ben. Megjegyzés: „e?”Még mindig megfelel a„ juhoknak ”; bár két "e" van a "juhban". Van itt egy árnyalat - lásd később.
n,
Ez megfelel egy előző karakter vagy előző csoport legalább n egymást követő ismétlésének. Tehát az „e 2,” regex megegyezik a cél két e-jével, a „juh” és a három „e” a cél „sheeep” -jével. Az „e 2,” nem egyezik a „set” -el, mert a „set” -nek csak egy „e” van.
n
Ez pontosan megegyezik egy előző karakter vagy megelőző csoport egymás után következő ismétlésével. Tehát az „e 2” regex megegyezik a cél két e-jével, „juh”. Az „e 2” nem egyezik a „set” -el, mert a „set” -nek csak egy „e” -je van. Nos, az „e 2” egyezik a cél két „e” -jével, „sheeep”. Van itt egy árnyalat - lásd később.
n, m
Ez megfelel egy előző karakter vagy előző csoport több egymást követő ismétlésének, n-től m-ig terjedően. Tehát az „e 1,3” nem felel meg semmit az „dig” -ben, amelyben nincs „e”. Egyezik az „e” betűvel a „készletben”, a két „e” a „juhban”, a három „e” a „sheeep” -ben és három „e” a „sheeepben”. Van egy árnyalat az utolsó mérkőzésen - lásd később.
Megfelelő váltakozás
Vegye figyelembe a következő célláncot a számítógépen.
„A gazdaságban különböző méretű disznók vannak.”
A programozó tudni akarja, hogy ennek a célpontnak van-e „kecskéje”, „nyúl” vagy „disznója”. A kód a következő lenne:
char str [] = "A gazdaságban különböző méretű sertések vannak.";if (regex_search (str, regex ("kecske | nyúl | disznó")))
cout << "matched" << endl;
más
cout << "not matched" << endl;
A kód egyezést eredményez. Vegye figyelembe az alternatív karakter használatát, |. Két, három, négy és több lehetőség lehet. A C ++ először megpróbálja összehangolni az első alternatívát, a „kecskét”, a cél karakterlánc minden karakterpozíciójában. Ha nem sikerül a „kecske”, akkor megpróbálja a következő alternatívát, a „nyulat”. Ha nem sikerül a „nyúl”, akkor megpróbálja a következő alternatívát, a „disznót”. Ha a „disznó” kudarcot vall, akkor a C ++ a célpont következő pozíciójára lép, és újra az első alternatívával indul.
A fenti kódban a „disznó” egyezik.
Egyezés kezdete vagy vége
Kezdet
Ha ^ a regex elején van, akkor a cél karaktersorozat kezdő szövege illeszthető a regexszel. A következő kódban a cél kezdete „abc”, amely megegyezik:
cout << "matched" << endl;
A következő kódban nem történik egyeztetés:
if (regex_search ("Igen, abc és def", regex ("^ abc")))cout << "matched" << endl;
más
cout << "not matched" << endl;
Itt az „abc” nincs a cél elején.
Megjegyzés: A '^' körkörös karakter egy metakarakter a regex elején, amely megfelel a cél karakterlánc elejének. Még mindig metakarakter a karakterosztály elején, ahol tagadja az osztályt.
Vége
Ha a $ a regex végén van, akkor a cél karaktersorozat befejező szövege illeszthető a regexszel. A következő kódban a cél vége az „xyz”, amely megfelel:
if (regex_search ("uvw és xyz", regex ("xyz $")))cout << "matched" << endl;
A következő kódban nem történik egyeztetés:
if (regex_search ("uvw és xyz final", regex ("xyz $")))cout << "matched" << endl;
más
cout << "not matched" << endl;
Itt az „xyz” nincs a cél végén.
Csoportosítás
A zárójelek felhasználhatók minták karaktereinek csoportosítására. Vegye figyelembe a következő regexet:
"koncert (zongorista)"A csoport itt „zongorista”, körülvéve metakarakterekkel (és). Valójában egy alcsoport, míg a „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ő az a személy, aki könyvekkel foglalkozik. Képzeljen el egy könyvtárat, amelyben egy könyvelő és egy könyvespolc található. Tegyük fel, hogy a következő célláncok egyike található a számítógépen:
"A könyvtárnak van egy könyvespolcja, amelyet csodálnak.";"Itt van a könyvelő.";
"A könyvelő a könyvespolccal dolgozik.";
Tegyük fel, hogy a programozónak nem az az érdeke, hogy tudja, melyik mondat található a számítógépen. Mégis érdekli, hogy a „könyvespolc” vagy „könyvelő” van-e jelen a számítógép bármely célpontjában. Ebben az esetben regexe lehet:
"könyvespolc | könyvelő."Váltakozás használata.
Figyelje meg, hogy a „könyv”, amely mindkét szóban közös, kétszer lett beírva, a minta két szavába. Annak elkerülése érdekében, hogy kétszer írja be a „könyv” szót, a regexet jobb lenne a következőképpen írni:
"könyv (polc | őrző)"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 végződéséhez használták. A C ++ egy csoportot entitásként kezel. Tehát a C ++ a „könyv” után azonnal megjelenő „polcot” vagy „őrzőt” fogja keresni. A következő kód kimenete „egyezik”:
char str [] = "A könyvtárnak van egy könyvespolcja, amelyet csodálnak.";if (regex_search (str, regex ("könyv (polc | őrző)")))
cout << "matched" << endl;
A „könyvespolc” és nem a „könyvelő” párosításra került.
Az ikáz és a többsoros regex_konstansok
icase
Az egyeztetés alapértelmezés szerint a kis- és nagybetűk közötti különbség. Lehet azonban kis- és nagybetűket tenni. Ehhez használja a regex :: icase konstansot, a következő kód szerint:
if (regex_search ("Visszajelzés", regex ("hírcsatorna", regex :: icase)))cout << "matched" << endl;
A kimenet „egyezik”. Tehát az „F” nagybetűs „visszajelzést” a „feed” és az „f” kisbetű. A „regex :: icase” lett a regex () konstruktor második argumentuma. Enélkül a nyilatkozat nem eredményezne egyezést.
Többsoros
Vegye figyelembe a következő kódot:
char str [] = "1. sor \ n 2. sor \ n 3. sor";if (regex_search (str, regex ("^.* $ ")))
cout << "matched" << endl;
más
cout << "not matched" << endl;
A kimenet „nem egyezik”. A regex: „^.* $, ”Megegyezik a cél karakterlánccal az elejétől a végéig. „.* ”Bármely karaktert jelent, kivéve \ n, nulla vagy annál többször. Tehát a cél új sorbeli karakterei (\ n) miatt nem voltak egyezések.
A cél egy többsoros karakterlánc. Annak érdekében, hogy '.'ahhoz, hogy megfeleljen az újsor karakterének, meg kell adni az állandó „regex :: multiline” kifejezést, a regex () konstrukció második argumentuma. A következő kód ezt szemlélteti:
char str [] = "1. sor \ n 2. sor \ n 3. sor";if (regex_search (str, regex ("^.* $ ", regex :: többsoros)))
cout << "matched" << endl;
más
cout << "not matched" << endl;
Az egész cél húr illesztése
A regress_match () függvény használható a teljes célláncra, amely nem rendelkezik új sor karakterrel (\ n). Ez a függvény különbözik a regex_search (). A következő kód ezt szemlélteti:
char str [] = "első második harmad";if (regex_match (str, regex (".*második.* ")))
cout << "matched" << endl;
Van itt egy meccs. Azonban vegye figyelembe, hogy a regex megegyezik a teljes céllánccal, és a célláncban nincs '\ n'.
A match_results objektum
A regex_search () függvény argumentumot vehet fel a cél és a regex objektum között. Ez az argumentum a match_results objektum. A teljes illesztett (rész) karakterlánc és az egyeztetett részhúrok megismerhetők vele. Ez az objektum egy speciális tömb metódusokkal. A match_results objektumtípus cmatch (karakterláncok esetén).
Meccsek megszerzése
Vegye figyelembe a következő kódot:
char str [] = "Az a nő, akit keresett!";cmatch m;
if (regex_search (str, m, regex ("w.m.n ")))
cout << m[0] << endl;
A cél karaktersorozatban a „nő” szó szerepel. A kimenet „nő”, amely megfelel a regexnek, „w.m.n ”. A nulla indexnél a speciális tömb tartja az egyetlen mérkőzést, amely „nő”.
Osztályopciókkal csak a célban talált első részlánc kerül a speciális tömbbe. A következő kód ezt szemlélteti:
cmatch m;if (regex_search ("A patkány, a macska, az ütő!", m, regex (" [bcr] at ")))
cout << m[0] << endl;
cout << m[1] << endl;
cout << m[2] << endl;
A kimenet „patkány” a nullától. m [1] és m [2] üres.
Alternatívákkal csak a célban talált első alhúr kerül a speciális tömbbe. A következő kód ezt szemlélteti:
if (regex_search ("A nyúl, a kecske, a disznó!", m, regex (" kecske | nyúl | disznó ")))cout << m[0] << endl;
cout << m[1] << endl;
cout << m[2] << endl;
A kimenet „nyúl” a nullától. m [1] és m [2] üres.
Csoportosítás
Csoportok bevonásakor a teljes minta illeszkedik a speciális tömb nulla cellájába. A következő megtalált alhúr az 1. cellába kerül; a következő alhúr a 2. cellába megy; stb. A következő kód ezt szemlélteti:
if (regex_search ("Ma a legjobb könyvkereskedő!", m, regex (" könyv ((sel) (ler)) ")))cout << m[0] << endl;
cout << m[1] << endl;
cout << m[2] << endl;
cout << m[3] << endl;
A kimenet:
könyvkereskedőeladó
sel
ler
Vegye figyelembe, hogy a csoport (eladó) a csoport (sel) elé kerül.
A mérkőzés helyzete
A cmatch tömb egyes alhúrjainak egyezési helye ismeretes. A számlálás a cél karakterlánc első karakterétől kezdődik, a nulla pozícióban. A következő kód ezt szemlélteti:
cmatch m;if (regex_search ("Ma a legjobb könyvkereskedő!", m, regex (" könyv ((sel) (ler)) ")))
cout << m[0] << "->" << m.position(0) << endl;
cout << m[1] << "->" << m.position(1) << endl;
cout << m[2] << "->" << m.position(2) << endl;
cout << m[3] << "->" << m.position(3) << endl;
Ne feledje, hogy argumentumként használja a position tulajdonságot, a cellaindex mellett. A kimenet:
könyvkereskedő-> 5eladó-> 9
sel-> 9
ler-> 12
Keresés és csere
Egy új szó vagy kifejezés helyettesítheti a mérkőzést. Ehhez a regex_replace () függvényt használják. Ezúttal azonban a karakterlánc, ahol a helyettesítés megtörténik, a karakterlánc objektum, nem pedig a karakterlánc. Tehát a string könyvtárat be kell vonni a programba. Ábra:
#include#include
#include
névtér használata std;
int main ()
string str = "Itt jön az emberem. Oda megy az embered.";
string newStr = regex_replace (str, regex ("férfi"), "nő");
cout << newStr << endl;
visszatér 0;
Az itt kódolt regex_replace () függvény az összes egyezést helyettesíti. 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 egy új karakterláncot ad vissza, amely a cél, de a helyére lép. A kimenet:
- Itt jön a nőm. Oda megy a nője.”
Következtetés
A reguláris kifejezés mintákat használ a célszekvencia karaktersorozatának részsorainak összehangolásához. A minták metakarakterekkel rendelkeznek. A C ++ reguláris kifejezések leggyakrabban használt függvényei: regex_search (), regex_match () és regex_replace (). A regex kettős idézőjelben szereplő minta. Ezek a függvények azonban a regex objektumot érvelik, és nem csak a regexet. A regexet regex objektummá kell tenni, mielőtt ezek a függvények használni tudnák.