Denne strengen kan være inne i datamaskinen, og brukeren vil kanskje vite om den har ordet "mann". Hvis det har ordet mann, kan han kanskje endre ordet "mann" til "kvinne"; slik at strengen skal lese:
"Her er kvinnen min.""Det er mange andre ønsker som disse fra datamaskinbrukeren; Noen er sammensatte. Regelmessig uttrykk, forkortet, regex, er gjenstand for å håndtere disse problemene av datamaskinen. C ++ kommer med et bibliotek som heter regex. Så et C ++ -program for å håndtere regex bør begynne med:
#inkludereDenne artikkelen forklarer grunnleggende uttrykk for vanlige uttrykk i C++.
Artikkelinnhold
Regelmessige uttrykk for grunnleggende
Regex
En streng som “Her er mannen min.”Over er målsekvensen eller målstrengen eller bare mål. “Mann”, som ble søkt etter, er det vanlige uttrykket, eller ganske enkelt, regex.
Matchende
Matching sies å oppstå når ordet eller setningen som blir søkt etter ligger. Etter matching kan en erstatning finne sted. Etter at "mann" er lokalisert ovenfor, kan den erstattes av "kvinne".
Enkel matching
Følgende program viser hvordan ordet “mann” blir matchet.
#inkludereFunksjonen regex_search () returnerer sant hvis det er en kamp og returnerer falsk hvis ingen kamp oppstår. Her tar funksjonen to argumenter: den første er målstrengen, og den andre er regex -objektet. Regex i seg selv er "mann", i dobbeltkjørt. Den første uttalelsen i Main () -funksjonen danner Regex -objektet. Regex er en type, og Reg er regex -objektet. Ovennevnte utdata er "matchet", som "mann" sees i målstrengen. Hvis "mann" ikke ble sett i målet, ville regex_search () ha returnert falsk, og utgangen ville blitt "ikke matchet".
Utgangen fra følgende kode er "ikke matchet":
regex reg ("mann");Ikke matchet fordi regex "mann" ikke ble funnet i hele målstrengen, "her er min å lage.""
Mønster
Det vanlige uttrykket, "mann" ovenfor, er veldig enkelt. Regexes er vanligvis ikke så enkle. Regelmessige uttrykk har metakaraktører. Metacharacters er karakterer med spesielle betydninger. En metakarakter er en karakter om karakterer. C ++ Regex Metacharacters er:
^ $ \ . * + ? () [] |En regex, med eller uten metakaraktører, er et mønster.
Karakterklasser
Firkantede parenteser
Et mønster kan ha karakterer i firkantede parenteser. Med dette vil en bestemt posisjon i målstrengen samsvare med noen av de firkantede partene sine karakterer. Tenk på følgende mål:
"Katten er i rommet.""Regex, [CBR] på ville matche Cat i det første målet. Det ville matche flaggermus i det andre målet. Det ville matche rotte i det tredje målet. Dette er fordi "katt" eller "flaggermus" eller "rotte" begynner med 'c' eller 'b' eller 'r'. Følgende kodesegment illustrerer dette:
regex reg ("[cbr] at");Utgangen er:
matchetUtvalg av karakterer
Klassen, [CBR] i mønsteret [CBR], ville matche flere mulige karakterer i målet. Det ville matche 'C' eller 'B' eller 'R' i målet. Hvis målet ikke har noe av 'C' eller 'B' eller 'R', etterfulgt av "at", ville det ikke være noen kamp.
Noen muligheter som 'C' eller 'B' eller 'R' eksisterer i et område. Utvalget av sifre, 0 til 9 har 10 muligheter, og mønsteret for det er [0-9]. Utvalget av små alfabeter, A til Z, har 26 muligheter, og mønsteret for det er [A-Z]. Utvalget av store alfabeter, A til Z, har 26 muligheter, og mønsteret for det er [A-Z]. - er ikke offisielt en metakarakter, men innenfor firkantede parenteser vil det indikere et område. Så følgende produserer en kamp:
if (regex_search ("id6id", regex ("[0-9]"))))Legg merke til hvordan regexen er konstruert som det andre argumentet. Kampen skjer mellom sifferet, 6 i området, 0 til 9, og 6 i målet, “Id6ID”. Ovennevnte kode tilsvarer:
if (regex_search ("id6id", regex ("[0123456789]")))Følgende kode produserer en kamp:
char str [] = "id6ie";Merk at det første argumentet her er en strengvariabel og ikke strengen bokstavelig. Kampen er mellom 'I' i [A-Z] og 'I' i "Id6ie".
Ikke glem at et område er en klasse. Det kan være tekst til høyre for området eller til venstre for rekkevidden i mønsteret. Følgende kode produserer en kamp:
if (regex_search ("ID2IDPOST-95222 -__ DDELINK__294_3116034780"> er en ID ", REGEX (" ID [0-9] ID ")))Kampen er mellom “ID [0-9] ID” og “ID2ID”. Resten av målstrengen, "er en ID," er ikke matchet i denne situasjonen.
Som brukt i det vanlige uttrykkets emne (regexes), betyr ordklassen faktisk et sett. Det vil si at en av karakterene i settet er å matche.
Merk: bindestrek - er en metakarakter bare innen firkantede parenteser, noe som indikerer et område. Det er ikke en metakarakter i regexen, utenfor de firkantede parentesene.
Negasjon
En klasse inkludert et område kan negeres. Det vil si at ikke av karakterene i settet (klassen) skal samsvare. Dette er indikert med ^ metakarakteren i begynnelsen av klassemønsteret, like etter åpningsfeltbraketten. Så [^0-9] betyr å matche karakteren i riktig posisjon i målet, som ikke er noen karakter i området, 0 til 9 inklusive. Så følgende kode vil ikke produsere en kamp:
if (regex_search ("0123456789101112", regex ("[^0-9]")))Et siffer innenfor området 0 til 9 ble funnet i noen av målstrengposisjonene, “0123456789101112,”; Så det er ingen kamp - negasjon.
Følgende kode produserer en kamp:
if (regex_search ("abcdefghij", regex ("[^0-9]")))Ingen siffer ble funnet i målet, "abcdefghij,"; Så det er en kamp.
[A-Z] er et område utenfor [^A-Z]. Og så [^a-z] er negasjonen av [A-Z].
[A-Z] er et område utenfor [^A-Z]. Og så [^a-z] er negasjonen av [A-Z].
Andre negasjoner eksisterer.
Matchende hvitespaser
"Eller \ t eller \ r eller \ n eller \ f er en hvitromkarakter. I følgende kode samsvarer regex, "\ n" '\ n' i målet:
if (regex_search ("av linje en.\ r \ nof line to.", regex (" \ n ")))Matcher et hvilket som helst hvitromskarakter
Mønsteret eller klassen for å matche et hvilket som helst hvitt romkarakter er, [\ t \ r \ n \ f]. I følgende kode er "matchet:
if (regex_search ("One Two", regex ("[\ t \ r \ n \ f]")))Matcher ethvert ikke-hvittromskarakter
Mønsteret eller klassen for å matche ethvert ikke-hvitt romkarakter er, [^ \ t \ r \ n \ f]. Følgende kode produserer en kamp fordi det ikke er noen hvitrom i målet:
if (regex_search ("1234abcd", regex ("[^ \ t \ r \ n \ f]")))Perioden (.) i mønsteret
Perioden (.) i mønsteret samsvarer med enhver karakter inkludert seg selv, bortsett fra \ n, i målet. En kamp produseres i følgende kode:
if (regex_search ("1234abcd", regex (".")))Ingen matchende resulterer i følgende kode fordi målet er "\ n".
if (regex_search ("\ n", regex (".")))Merk: Inne i en karakterklasse med firkantede parenteser har perioden ingen spesiell betydning.
Matchende repetisjoner
En karakter eller en gruppe tegn kan forekomme mer enn en gang i målstrengen. Et mønster kan samsvare med denne repetisjonen. Metakarakterene, ?, *, +og brukes til å matche repetisjonen i målet. Hvis X er et tegn av interesse i målstrengen, har metakarakterene følgende betydninger:
x*: betyr match 'x' 0 eller flere ganger, jeg.e., Ethvert antall gangerDisse metakarakterene kalles kvantifiserere.
Illustrasjoner
*
* Samsvarer med den foregående karakteren eller foregående gruppen, null eller flere ganger. “O*” matcher 'O' i “Hund” av målstrengen. Det samsvarer også med "oo" i "bok" og "ser". Regex, “O*” stemmer overens.”. Merk: “O*” samsvarer med “Dig”, der 'O' forekommer null (eller mer) tid.
+
+ Samsvarer med den foregående karakteren eller foregående gruppen, 1 eller flere ganger. Kontrast det med null eller flere ganger for *. Så regex, “E+” matcher 'E' i “Eat”, der 'E' forekommer en gang. “E+” samsvarer også med “EE” i “Sheep”, der 'E' forekommer mer enn en gang. Merk: “E+” vil ikke samsvare med “Dig” fordi i “Dig”, 'E' forekommer ikke minst en gang.
?
De ? Matcher den foregående karakteren eller foregående gruppen, 0 eller 1 gang (og ikke mer). Så, “E?”Matcher“ Dig ”fordi 'E' forekommer i“ Dig ”, null tid. “E?”Samsvarer“ sett ”fordi 'e' forekommer i“ sett ”, en gang. Merk: “E?”Matcher fortsatt“ sauer ”; Selv om det er to 'E -er i "sauer". Det er en nyanse her - se senere.
n,
Dette samsvarer minst med påfølgende repetisjoner av en foregående karakter eller foregående gruppe. Så regex, "e 2," samsvarer med de to 'E -ene i målet, "sauer", og de tre' e i målet "sheeep". “E 2,” samsvarer ikke med “Set”, fordi “Set” bare har en 'E'.
n
Dette samsvarer nøyaktig med påfølgende repetisjoner av en foregående karakter eller foregående gruppe. Så regex, "E 2" samsvarer med de to 'E -ene i målet, "sauer". “E 2” samsvarer ikke med “Set” fordi “Set” bare har en 'E'. Vel, "E 2" samsvarer med to 'E -er i målet, "Sheeep". Det er en nyanse her - se senere.
n, m
Dette samsvarer med flere påfølgende repetisjoner av en foregående karakter eller foregående gruppe, hvor som helst fra N til M, inkludert. Så "E 1,3" samsvarer med ingenting i "Dig", som ikke har "E". Det samsvarer med den ene 'e' i "sett", de to 'e -er i "sauer", de tre' e -er i "sheeep", og tre 'e i "sheeeep". Det er en nyanse på forrige kamp - se senere.
Matchende veksling
Tenk på følgende målstreng på datamaskinen.
“Gården har griser i forskjellige størrelser.”
Programmereren vil kanskje vite om dette målet har "geit" eller "kanin" eller "gris". Koden vil være som følger:
char str [] = "Gården har griser i forskjellige størrelser.";Koden produserer en kamp. Legg merke til bruken av vekslingskarakteren, |. Det kan være to, tre, fire og flere alternativer. C ++ vil først prøve å matche det første alternativet, "geit", på hver karakterposisjon i målstrengen. Hvis det ikke lykkes med "geit", prøver det neste alternativ, "kanin". Hvis det ikke lykkes med "kanin", prøver det neste alternativ, "gris". Hvis "gris" mislykkes, går C ++ videre til neste posisjon i målet og starter med det første alternativet igjen.
I koden ovenfor er "gris" matchet.
Matchende begynnelse eller slutt
Begynnelse
Hvis ^ er i begynnelsen av regexen, kan begynnelsesteksten til målstrengen matches av regexen. I følgende kode er målet på målet “ABC”, som samsvarer med:
Ingen matching finner sted i følgende kode:
if (regex_search ("ja, abc og def", regex ("^abc"))))Her er "ABC" ikke i begynnelsen av målet.
Merk: Circumflex -karakteren, '^', er en metakarakter i starten av regexen, og samsvarer med starten av målstrengen. Det er fremdeles en metakarakter i starten av karakterklassen, der den negerer klassen.
Slutt
Hvis $ er på slutten av regexen, kan sluttteksten til målstrengen matches av regexen. I følgende kode er slutten av målet "XYZ", som er matchet:
if (regex_search ("UVW and XYZ", regex ("xyz $")))Ingen matching finner sted i følgende kode:
if (regex_search ("UVW og XYZ Final", Regex ("XYZ $")))Her er "xyz" ikke på slutten av målet.
Gruppering
Parenteser kan brukes til å gruppere tegn i et mønster. Tenk på følgende regex:
"En konsert (pianist)"Gruppen her er "pianist" omgitt av metakarakterene (og). Det er faktisk en undergruppe, mens "en konsert (pianist)" er hele gruppen. Vurder følgende:
"The (pianisten er bra)"Her er undergruppen eller understrengen: "Pianist er god".
Understrenger med vanlige deler
En bokholder er en person som tar seg av bøker. Se for deg et bibliotek med en bokholder og bokhylle. Anta at en av følgende målstrenger er i datamaskinen:
"Biblioteket har en bokhylle som er beundret.";Anta at programmererens interesse ikke er å vite hvilken av disse setningene som er på datamaskinen. Fortsatt er hans interesse å vite om "bokhylle" eller "bokholder" er til stede i hvilken som helst målstreng som er på datamaskinen. I dette tilfellet kan hans regex være:
"Bokhylle | Bokholder.""Ved hjelp av veksling.
Legg merke til at "bok", som er vanlig for begge ordene, er skrevet to ganger, med de to ordene i mønsteret. For å unngå å skrive "bok" to ganger, ville regexen bli bedre skrevet som:
"Bok (hylle | keeper)"Her har gruppen, "hylle | keeper" veksling metakarakteren fortsatt blitt brukt, men ikke for to lange ord. Det har blitt brukt til de to sluttdelene av de to lange ordene. C ++ behandler en gruppe som en enhet. Så C ++ vil se etter "hylle" eller "keeper" som kommer umiddelbart etter "bok". Utgangen fra følgende kode er "matchet":
char str [] = "Biblioteket har en bokhylle som er beundret.";“Bokhylle” og ikke “Bookholder” har blitt matchet.
Icase og multiline regex_constants
Icase
Matching er case sensitiv som standard. Imidlertid kan det gjøres til ensfølsom. For å oppnå dette, bruk regex :: icase konstant, som i følgende kode:
if (regex_search ("tilbakemelding", regex ("feed", regex :: icase)))Utgangen er "matchet". Så "Tilbakemelding" med store bokstaver 'F' har blitt matchet med "Feed" med små bokstaver 'F'. “Regex :: Icase” er blitt gjort til det andre argumentet fra Regex () konstruktøren. Uten det ville ikke uttalelsen gi en kamp.
Multiline
Tenk på følgende kode:
char str [] = "linje 1 \ nline 2 \ nline 3";Utgangen er "ikke matchet". Regexen, “^^.*$, ”Samsvarer med målstrengen fra begynnelsen til slutten. “.*”Betyr enhver karakter bortsett fra \ n, null eller flere ganger. Så på grunn av Newline -tegnene (\ n) i målet, var det ingen matching.
Målet er en multiline streng. For '.'For å matche Newline -karakteren, må den konstante "regex :: multiline" fremmes, det andre argumentet fra regex () konstruksjonen. Følgende kode illustrerer dette:
char str [] = "linje 1 \ nline 2 \ nline 3";Matcher hele målstrengen
For å matche hele målstrengen, som ikke har Newline -tegn (\ n), kan Regex_Match () -funksjonen brukes. Denne funksjonen er forskjellig fra regex_search (). Følgende kode illustrerer dette:
char str [] = "første andre tredje";Det er en kamp her. Legg imidlertid merke til at regex samsvarer med hele målstrengen, og målstrengen ikke har noen '\ n'.
Match_results -objektet
Regex_search () -funksjonen kan ta et argument mellom målet og regex-objektet. Dette argumentet er Match_Results -objektet. Hele matchede (del) strengen og understrengene som matches kan bli kjent med den. Dette objektet er et spesielt utvalg med metoder. Match_results -objekttypen er cmatch (for strenglitteraler).
Skaffe kamper
Tenk på følgende kode:
char str [] = "Kvinnen du lette etter!";Målstrengen har ordet "kvinne". Produksjonen er "kvinne", som tilsvarer regexen, "w.m.n ”. Hos Index Zero har den spesielle matrisen den eneste kampen, som er "kvinne".
Med klassealternativer blir bare den første understrengen som finnes i målet, sendt til den spesielle matrisen. Følgende kode illustrerer dette:
Cmatch M;Utgangen er "rotte" fra indeksen null. m [1] og m [2] er tomme.
Med alternativer blir bare den første understrengen som finnes i målet, sendt til den spesielle matrisen. Følgende kode illustrerer dette:
if (regex_search ("kaninen, geiten, grisen!", M, regex (" geit | kanin | gris ")))Utgangen er "kanin" fra indeks null. m [1] og m [2] er tomme.
Grupperinger
Når grupper er involvert, går det komplette mønsteret matchet, går inn i Cell Zero av den spesielle matrisen. Den neste understrengen som er funnet går i celle 1; Understrengende følgende går inn i celle 2; og så videre. Følgende kode illustrerer dette:
if (regex_search ("Beste bokhandler i dag!", M, Regex (" Book ((Sel) (ler)) "))))Utgangen er:
BooksellerMerk at gruppen (selger) kommer foran gruppen (SEL).
Matchposisjon
Posisjonen til kamp for hver understreng i CMatch-matrisen kan være kjent. Telling begynner fra den første tegnet til målstrengen, på posisjon null. Følgende kode illustrerer dette:
Cmatch M;Legg merke til bruken av posisjonsegenskapen, med celleindeksen, som et argument. Utgangen er:
Bookseller-> 5Søk og erstatt
Et nytt ord eller uttrykk kan erstatte kampen. Regex_replace () -funksjonen brukes til dette. Denne gangen er imidlertid strengen der erstatningen skjer strengobjektet, ikke strengen bokstavelig. Så strengbiblioteket må inkluderes i programmet. Illustrasjon:
#inkludereRegex_replace () -funksjonen, som kodet her, erstatter alle kampene. Det første argumentet for funksjonen er målet, det andre er regex -objektet, og det tredje er erstatningsstrengen. Funksjonen returnerer en ny streng, som er målet, men har erstatningen. Utgangen er:
“Her kommer kvinnen min. Der går kvinnen din.”
Konklusjon
Det vanlige uttrykket bruker mønstre for å matche underlag i målsekvensstrengen. Mønstre har metakarakter. Vanlige brukte funksjoner for C ++ vanlige uttrykk, er: regex_search (), regex_match () og regex_replace (). En regex er et mønster i dobbeltkjørt. Imidlertid tar disse funksjonene regex -objektet som et argument og ikke bare regex. Regex må gjøres til et regex -objekt før disse funksjonene kan bruke det.