# Regularni izrazi

    Ta dodatek vsebuje kratko, a upajmo, da zadostno in
    zajema uvod v svet običajnega
    izrazi. Dokumentira regularne izraze v obrazcu
    na voljo znotraj &kappname;, ki ni združljiv z običajnim
    izrazi perla, niti z izrazi naprimer
    grep.

## Uvod

Regularni izrazi nam omogočajo, da opišemo nekatere možne vsebine besedilnega niza na način, ki ga razume majhen kos programske opreme, tako da lahko razišče, ali se besedilo ujema, in tudi v primeru napredne aplikacije s sredstvi za shranjevanje kosov ali ujemajočega se besedila.

Primer: Recimo, da želite v besedilu poiskati odstavke, ki se začnejo z imeni Henrik ali Pernille, ki mu sledi neka oblika glagola say.

Z običajnim iskanjem bi začeli iskati prvo ime, Henrik, ki bi mu morda sledilo sa, takole: `Henrik sa`, in med iskanjem za ujemanja bi morali zavreči tiste, ki niso začetek odstavka, pa tudi tiste, v katerih beseda, ki se začne s črkama sa, ni bila niti pravi, rekel ali tako. In potem seveda vse to ponovite z naslednjim imenom ...

Z regularnimi izrazi je to nalogo mogoče opraviti z enim samim iskanjem in z večjo stopnjo natančnosti.

Da bi to dosegli, regularni izrazi določajo pravila za podrobno izražanje posplošitve niza za ujemanje. Naš primer, ki bi ga lahko dobesedno izrazili takole: Vrstica, ki se začne z Henrik ali Pernille (po možnosti sledijo do 4 presledki ali tabulatorji), ki ji sledi presledek, ki mu sledi sa in nato ys ali id, se lahko izrazi z naslednjim regularnim izrazom:

`^[ \t]{0,4}(Henrik|Pernille) sa(ys|id)`

Zgornji primer prikazuje vse štiri glavne koncepte sodobnih regularnih izrazov, in sicer:

- Vzorci

- Trditve

- Kvantifikatorji

- Reference za nazaj

Karetica (`^`), ki začne izraz, je trditev, ki je resnična samo, če je naslednji ujemajoči se niz na začetku vrstice.

Niza `[ \t]` in `(Henrik|Pernille) sa(ys|id)` sta vzorca. Prvi je razred znakov, ki se ujema s praznim ali (vodoravnim) tabulatorjem; drugi vzorec vsebuje najprej podvzorec, ki se ujema bodisi z `Henrik` ali `Pernille`, nato kos, ki se ujema z natančnim nizom `sa` in končno podvzorec, ki se ujema z `ys` ali `id`

Niz `{0,4}` je kvantifikator, ki pravi kjer koli od 0 do 4 prejšnjega.

Ker programska oprema za regularne izraze, ki podpira koncept povratnih sklicev, shrani celoten ujemajoči se del niza kot tudi podvzorce, obdane z oklepaji, bi lahko dobili nekaj načinov dostopa do teh sklicev bodisi celotno ujemanje (pri iskanju besedilnega dokumenta v urejevalniku z regularnim izrazom, ki je pogosto označen kot izbrano) bodisi najdeno ime ali zadnji del glagola.

Vse skupaj se bo izraz ujemal tam, kjer smo želeli, in samo tam.

Naslednji razdelki bodo podrobno opisali, kako zgraditi in uporabiti vzorce, razrede znakov, trditve, kvantifikatorje in povratne reference, zadnji del pa bo dal nekaj uporabnih primerov.

## Vzorci

Vzorci so sestavljeni iz dobesednih nizov in znakovnih razredov. Vzorci lahko vsebujejo podvzorce, ki so vzorci v oklepajih.

### Ubežni znaki

Tako v vzorcih kot tudi v razredih znakov imajo nekateri znaki poseben pomen. Če se želite dobesedno ujemati s katerim koli od teh znakov, jih je treba označiti ali ubežati, da programska oprema za regularne izraze ve, da mora take znake interpretirati v njihovem dobesednem pomenu.

To naredite tako, da pred znak dodate poševnico nazaj (`\`).

Programska oprema za regularne izraze bo tiho prezrla ubežanje znaka, ki v kontekstu nima posebnega pomena, zato je ubežanje na primer j (`\j`) varno. Če ste v dvomih, ali ima znak lahko poseben pomen, se mu torej lahko varno izognete.

Ubežanje seveda vključuje sam znak nazaj poševnice, da bi se dobesedno ujemal s takim, bi napisali `\\`.

### Razredi znakov in okrajšave

Razred znakov je izraz, ki se ujema z enim od definiranega niza znakov. V regularnih izrazih so razredi znakov definirani z dajanjem zakonitih znakov za razred v oglate oklepaje, `[]`, ali z uporabo enega od skrajšanih razredov, opisanih spodaj.

Preprosti razredi znakov vsebujejo samo enega ali več dobesednih znakov, na primer `[abc]` (ki se ujema s katero koli od črk a, b ali c) ali `[0123456789]` (ujema se s katero koli števko).

Ker imajo črke in števke logičen vrstni red, jih lahko skrajšate tako, da določite njihove obsege: `[a-c]` je enako `[abc]` in `[0-9 ]` je enako `[0123456789]`. Združevanje teh konstruktov, na primer `[a-fynot1-38]`, je popolnoma zakonito (zadnji bi se seveda ujemal s katerim koli od a,b,c,d, e,f,y, >n,o,t, 1,2,3 > ali 8).

Ker so velike črke različni znaki od njihovih nevelikih ustreznikov, morate za ustvarjanje razreda znakov brez velikih in velikih črk, ki se ujema z a ali b, v vsakem primeru napisati `[aAbB]`.

Seveda je mogoče ustvariti negativen razred, ki se ujema kot karkoli, vendar Če želite to narediti, postavite kazalko (`^`) na začetek razreda :

`[^abc]` se bo ujemal s katerim koli znakom ampak a, b ali c.

Poleg dobesednih znakov je definiranih nekaj okrajšav, ki olajšajo življenje:

`\a`

- To se ujema z &ASCII; znak zvonca (BEL, 0x07).

`\f`

- To se ujema z &ASCII; znak podajanja obrazca (FF, 0x0C).

`\n`

- To se ujema z &ASCII; znak za začetek vrstice (LF, 0x0A, nova vrstica Unix).

`\r`

- To se ujema z &ASCII; znak za vrnitev na začetek (CR, 0x0D).

`\t`

- To se ujema z &ASCII; horizontalni tabulator (HT, 0x09).

`\v`

- To se ujema z &ASCII; navpični tabulator (VT, 0x0B).

`\xhhhh`

- To se ujema z znakom Unicode, ki ustreza šestnajstiškemu številu hhhh (med 0x0000 in 0xFFFF). \0ooo (&ie;, \nič ooo) se ujema z znakom &ASCII;/Latin-1, ki ustreza osmiškemu številu ooo (med 0 in 0377).

`.` (pika)

- To se ujema s katerim koli znakom (vključno z novo vrstico).

`\d`

- To se ujema s števko. Enako `[0-9]`

`\D`

- To se ujema z neštevilko. Enako `[^0-9]` ali `[^\d]`

`\s`

- To se ujema s presledkom. Praktično enako `[ \t\n\r]`

`\S`

- To se ujema s presledkom, ki ni prazen. Praktično enako `[^ \t\r\n]` in enako `[^\s]`

`\w`

- Ujema se s katerim koli besednim znakom - v tem primeru s katero koli črko, številko ali podčrtajem. Enako `[a-zA-Z0-9_]`

`\W`

- Ujema se s katerim koli nebesednim znakom - karkoli razen črk, številk ali podčrtaja. Enako `[^a-zA-Z0-9_]` ali `[^\w]`

Podprt je tudi Zapis razredov POSIX, `[:<ime razreda>:]`. Na primer, `[:digit:]` je enakovreden `\d` in `[:space:]` `\s`. Oglejte si celoten seznam znakovnih razredov POSIX tukaj.

Skrajšane razrede lahko postavite v razred po meri, na primer, da se ujemajo z besednim znakom, presledkom ali piko, lahko napišete `[\w \.]`

#### Znaki s posebnimi pomeni znotraj razredov znakov

Naslednji znaki imajo poseben pomen znotraj konstrukcije razreda znakov [] in jih je treba ubežati, da so dobesedno vključeni v razred:

`]`

- Konča razred znakov. Mora biti ubežno, razen če je prvi znak v razredu (lahko sledi neubežni kazalki).

`^` (kazalka)

- Označuje negativen razred, če je prvi znak. Če je prvi znak v razredu, ga je treba ubežati, da se dobesedno ujema.

`-` (pomišljaj)

- Označuje logično območje. Vedno mora biti ubežen znotraj razreda znakov.

`\` (poševnica nazaj)

- Pobegli znak. Vedno je treba pobegniti.

### Alternative: ujemanje z enim od

Če se želite ujemati z enim od nabora alternativnih vzorcev, jih lahko ločite z `|` (znak navpične črte).

Na primer, da bi našli John ali Harry, bi uporabili izraz `John|Harry`.

### Podvzorci

Podvzorci so vzorci v oklepajih in imajo več uporab v svetu regularnih izrazov.

#### Določanje alternativ

Podvzorec lahko uporabite za združevanje nabora alternativ znotraj večjega vzorca. Alternative so ločene z znakom | (navpična črta).

Če želite na primer ujemati eno od besed int, float ali double, lahko uporabite vzorec `int|float|double`. Če želite enega najti le, če mu sledi nekaj presledkov in nato nekaj črk, postavite alternative znotraj podvzorca: `(int|float|double)\s+\w+`.

#### Zajem ujemajočega se besedila (povratne reference)

Če želite uporabiti povratni sklic, uporabite podvzorec `(PATTERN)`, da si zapomnite želeni del vzorca. Če želite preprečiti, da bi si podvzorec zapomnil, uporabite nezajemljivo skupino `(?:PATTERN)`.

Na primer, če želite poiskati dve pojavitvi iste besede, ločeni z vejico in po možnosti s presledkom, lahko napišete `(\w+),\s*\1`. Podvzorec `\w+` bi našel kos besednih znakov in celoten izraz bi se ujemal, če bi jim sledila vejica, 0 ali več presledkov in nato enak kos besednih znakov. (Niz `\1` se sklicuje na prvi podvzorec, obdan z oklepaji.)

Da bi se izognili dvoumnostim z uporabo `\1` z nekaj števkami za njim (⪚ `\12` je lahko 12. podvzorec ali samo prvi podvzorec z `2` ) uporabljamo `\{12}` kot sintakso za večmestne podvzorce.

Primeri:

- `\{12}1` je uporabi podvzorec 12

- `\123` je uporabi zajem 1 in nato 23 kot običajno besedilo

#### Trditve za pogled naprej

Trditev vnaprejšnjega pogleda je podvzorec, ki se začne z `?=` ali `?!`.

Na primer, če želite ujemati dobesedni niz Bill, vendar le, če mu ne sledi Gates, lahko uporabite ta izraz: `Bill(?! Gates)`. (S tem bi našli Billa Clintona kot tudi Billy the kid, vendar bi prezrli druga ujemanja.)

Podvzorci, uporabljeni za trditve, niso zajeti.

Glejte tudi Trditve.

#### Lookbehind trditve

Trditev za nazaj je podvzorec, ki se začne z `?<=` ali `?<!`.

Lookbehind ima enak učinek kot lookahead, vendar deluje nazaj. Na primer, če želite ujemati dobesedni niz sadje, vendar le, če pred njim ni grozdje, lahko uporabite ta izraz: `(?<!grozdje)sadje`.

Podvzorci, uporabljeni za trditve, niso zajeti.

Glejte tudi Trditve

### Znaki s posebnim pomenom znotraj vzorcev

Naslednji znaki imajo pomen znotraj vzorca in jih je treba ubežati, če jih želite dobesedno ujemati:

`\` (poševnica nazaj)

- Pobegli zank.

`^` (kazalka)

- Premakni kazalko na začetek vrstice.

`$`

- Uveljavi konec niza.

`()` (levi in desni oklepaj)

- Označuje podvzorce.

`{}` (levi in desni zavit oklepaj)

- Označuje numerične kvantifikatorje.

`[]` (levi in desni oglati oklepaj)

- Označuje razrede znakov.

`|` (navpična vrstica)

- logični ALI. Ločuje alternative.

`` (znak plus)

- Kvantifikator, 1 ali več.

`*` (zvezdica)

- Kvantifikator, 0 ali več.

`?` (vprašaj)

- Izbirni znak. Lahko se razlaga kot kvantifikator, 0 ali 1.

## Kvantifikatorji

Kvantifikatorji omogočajo, da se regularni izraz ujema z določenim številom ali obsegom števil znaka, razreda znakov ali podvzorca.

Kvantifikatorji so v zavitih oklepajih (`{` in `}`) in imajo splošno obliko `{[minimum-occurrences][,[maximum-occurrences]]}`

Uporabo je najbolje pojasniti s primerom:

`{1}`

- Točno 1 pojavitev

`{0,1}`

- Nič ali 1 pojavitev

`{,1}`

- Enako, z manj dela;)

`{5,10}`

- Vsaj 5, vendar največ 10 pojavitev.

`{5,}`

- Vsaj 5 pojavitev, brez največje vrednosti.

Poleg tega obstaja nekaj okrajšav:

`*` (zvezdica)

- podobno kot `{0,}`, najdi poljubno število pojavitev.

`` (znak plus)

- podobno kot `{1,}`, vsaj 1 pojavitev.

`?` (vprašaj)

- podobno kot `{0,1}`, nič ali 1 pojavitev.

### Pohlep

Pri uporabi kvantifikatorjev brez največje vrednosti se regularni izrazi privzeto ujemajo s čim večjim delom iskanega niza, splošno znano kot pohlepno vedenje.

Sodobna programska oprema za regularne izraze nudi sredstva za izklop požrešnosti, čeprav je v grafičnem okolju odvisno od vmesnika, ki vam omogoči dostop do te funkcije. Na primer, iskalno pogovorno okno, ki ponuja iskanje po regularnem izrazu, bi lahko imelo potrditveno polje z oznako Minimalno ujemanje, prav tako pa bi moralo označevati, ali je požrešnost privzeto vedenje.

### V primerih konteksta

Tukaj je nekaj primerov uporabe kvantifikatorjev:

`^\d{4,5}\s`

- Ujema se s številkami v 1234 go in 12345 zdaj, vendar ne v 567 enajst niti v 223459 nekje.

`\s`

- Ujema se z enim ali več presledki.

`(bla){1,}`

- Ujema se z vsemi blablabla in bla v blackbird ali tabla.

`/?>`

- Ujema se s /> v <closeditem/> kot tudi > v <openitem>.

## Trditve

Trditve omogočajo ujemanje regularnega izraza samo pod določenimi nadzorovanimi pogoji.

Trditev ne potrebuje znaka za ujemanje, temveč razišče okolico možnega ujemanja, preden ga potrdi. Na primer, trditev o besedni meji ne poskuša najti nebesednega znaka nasproti besednega znaka ena na njegovem mestu, temveč poskrbi, da ni besednega znaka. To pomeni, da se lahko trditev ujema tam, kjer ni znaka, &ie; na koncih iskanega niza.

Nekatere trditve dejansko imajo vzorec za ujemanje, vendar del ujemajočega se niza, ki ne bo del rezultata ujemanja polnega izraza.

Regularni izrazi, kot so dokumentirani tukaj, podpirajo naslednje trditve:

`^` (karetica: začetek niza)

- Premakni kazalko na začetek vrstice.

  Izraz `^Peter` se bo ujemal pri Peter v nizu Peter, hej!, vendar ne v Hej, Peter!

`$` (konec niza)

- Ujema se s koncem iskanega niza.

  Izraz `you\?$` se bo zadnjič ujemal z vami v nizu Tega niste storili, kajne? vendar nikjer v You didn't do to, kajne?

`\b` (besedna meja)

- Ujema se, če je na eni strani besedni znak, na drugi pa ne.

  To je uporabno za iskanje koncev besed, na primer obeh koncev za iskanje cele besede. Izraz `\bin\b` se bo ujemal pri ločenem in v nizu On je prišel skozi okno, vendar ne pri v v oknu.

`\B` (brez besedne meje)

- Ujema se povsod, kjer se \b ne ujema.

  To pomeni, da se bo ujemal na primer znotraj besed: Izraz `\Bin\B` se bo ujemal v oknu, ne pa v integer ali Zaljubljen sem.

`(?=PATTERN)` (Pozitiven pogled naprej)

- Trditev vnaprejšnjega pogleda gleda na del niza, ki sledi možnemu ujemanju. Pozitiven pogled naprej bo preprečil ujemanje niza, če se besedilo, ki sledi možnemu ujemanju, ne ujema z VZORCE trditve, vendar besedilo, ki se ujema s tem, ne bo vključeno v rezultat.

  Izraz `handy(?=\w)` se bo ujemal z handy v handyman, ne pa tudi z To je prišlo prav!

`(?!PATTERN)` (Negativni pogled naprej)

- Negativni pogled naprej preprečuje morebitno ujemanje, če se naslednji del iskanega niza ujema z njegovim VZORCEM.

  Izraz `const \w+\b(?!\s*&)` se bo ujemal pri const char v nizu const char* foo, medtem ko ne more se ujemati z const QString v const QString& bar, ker se & ujema z vzorcem trditve negativnega vnaprejšnjega pogleda.

`(?<=PATTERN)` (Pozitiven pogled nazaj)

- Lookbehind ima enak učinek kot lookahead, vendar deluje nazaj. Pogled nazaj pogleda del niza pred možnim ujemanjem. Pozitivni pogled nazaj se bo ujemal z nizom samo, če je pred njim VZOREC trditve, vendar besedilo, ki se ujema s tem, ne bo vključeno v rezultat.

  Izraz `(?<=cup)cake` se bo ujemal pri cake, če ga nasledi cup (v cupcake vendar ne samo v cheesecake ali v cake).

`(?<!PATTERN)` (Negativni pogled zadaj)

- Negativni pogled za nazaj preprečuje morebitno potrditev ujemanja, če se prejšnji del iskanega niza ujema z njegovim VZORCEM.

  Izraz `(?<![\w\.])[0-9]+` se bo ujemal pri 123 v nizih =123 in -123, medtem ko se ne more ujemati z 123 v .123 ali word123.

`(PATTERN)` (skupina za zajem)

- Podvzorec v oklepajih se zajame in zapomni, tako da ga je mogoče uporabiti v povratnih sklicih. Na primer, izraz `(&quot;+)[^&quot;]*\1` se ujema z `""""besedilo""""` in `"besedilo"`.

  Za več informacij glejte razdelek Zajem ujemajočega se besedila (povratne reference).

`(?:PATTERN)` (skupina brez zajemanja)

- Podvzorec v oklepajih ni zajet in si ni zapomnil. Priporočljivo je, da vedno uporabite skupine brez zajetja, če zajetja ne boste uporabili.