Hlavní navigace

Regulární výrazy (4)

Pavel Satrapa 28. 4. 2000

Po krátké odbočce se vracíme k opakování. Onu přestávku věnovanou programům podporujícím regulární výrazy jsem zařadil jednak abych předvedl nějaké praktické využití, jednak proto, že již nebude možné skrývat existenci různých dialektů. Různé programy totiž podporují lehce odlišné varianty regulárních výrazů. Ty, o kterých jsem mluvil až dosud, byly společné pro všechny. Dnes už narazíme na některé odlišnosti.

Omezený počet opakování

Základním problémem klasické opakovací hvězdičky je, že je nekontrolovatelná. Pro některé situace potřebujete přesnější vyjadřování.

Vaše touhy uspokojí konstrukce \{min,max\}. Opět se vztahuje na bezprostředně předcházející regulární výraz a říká, že se má opakovat alespoň min-krát, nanejvýš však max-krát. Jako každé opakování i tohle je hladové, takže se snaží uplatnit vždy co největší z povoleného počtu opakování.

Příklad:

Regulárnímu výrazu i\{1,3\} vyhoví řetězce „i“, „ii“ nebo „iii“.

Tvar tohoto opakovátka je velmi variabilní. Pokud chybí horní mez (\{min,\}), znamená to, že maximální počet opakování je neomezený. Jestliže v konstrukci použijete jen samotné číslo (\{počet\}), musí se regulární výraz opakovat přesně daný počet-krát.

Příklad:

Regulární výraz pro rodné číslo by vypadal takto:

[0-9]\{6\}/[0-9]\{3,4\}

Šest číslic, lomítko a ještě tři nebo čtyři číslice.

A již tu máme první odlišnost. V některých verzích regulárních výrazů (například v Perlu) se při omezování počtu opakování před složenými závorkami nepíší zpětná lomítka. Zapíšete-li zde \{, znamená to, že zkoumaný text má obsahovat znak „{“. Perl má pro tuto specialitu dobrou omluvu: zavedl pravidlo, že kombinace zpětného lomítka a znaku odlišného od písmena či číslice nikdy nemá speciální význam a vždy představuje dotyčný znak.

Nejpopulárnější opakovačky

Dva velmi populární případy opakování si vysloužily svůj vlastní speciální znak. Prvním je „alespoň jeden výskyt“ - tedy cosi velmi podobného klasické opakovací hvězdičce, až na to, že opakovaný regulární výraz nelze vynechat. Stejného efektu dosáhnete konstrukcí \{1,\}, ale to je příliš složité psaní. Proto se alespoň jeden výskyt předchozího regulárního výrazu zapisuje znakem plus (+).

Druhou populární situací je nepovinný (čili nanejvýš jeden) výskyt. Opět jej lze zapsat pomocí \{0,1\}, ale kratší je otazník (?).

Dialekty regulárních výrazů se u této dvojice znaků opět silně rozcházejí. Programy používající klasické regulární výrazy (grep, sed, vi) jim předřazují zpětné lomítko (\+ a \?). Generace, která implementuje rozšířené regulární výrazy, (egrep, awk, Perl) je píše bez něj (+ a ?).

Příklad:

Alespoň jedna číslice se tedy v grep, sed a vi vyjádří pomocí [0–9]\+, zatímco egrep, awk či Perl nabízí kratší [0–9]+. Zápis můžeme lehce rozšířit na regulární výraz pro celé číslo: nepovinné znaménko následované alespoň jednou číslici. V klasických regulárních výrazech to bude [-+]\?[0–9]\+, zatímco v rozšířených [-+]?[0–9]+.

Pozice

Výrok „dejte mi pevný bod a pohnu zeměkoulí“ jistě znáte. Nahlíženo jeho optikou byly všechny naše dosavadní regulární výrazy poněkud neukotvené. Řetězec, který jim vyhovuje, se mohl vyskytovat kdekoli ve zkoumaném textu. Občas však člověk musí být přísnější.

Proto regulární výrazy nabízejí několik speciálních pozičních znaků. Těmi nejznámějšími jsou stříška (^), která ztělesňuje začátek řádku (resp. zkoumaného řetězce znaků), a dolar ($) označující jeho konec.

Příklad:

grep ‚^#‘ vám tedy najde řádky začínající znakem ‚#‘, grep ‚[0–9]$‘ řádky končící číslicí a konečně grep ‚^-\+$‘ řádky složené pouze z pomlček (nikoli však prázdné).

Dalším významným místem je hranice slova. Ve většině regulárních dialektů máte k dispozici konstrukci \<, která označuje začátek slova, a \>, které vyhoví pouze jeho konec.

Perl nerozlišuje začátek slova od konce, má pouze speciální znak \b pro „hranici slova“ (tedy začátek nebo konec). Ovšem dlužno přiznat, že z okolního kontextu bývá zřejmé, zda \b může vyhovět začátek nebo konec slova. Jako cenu útěchy získáváte v Perlu ještě \B, kterému vyhoví libovolné místo ve zkoumaném řetězci kromě hranice slova. Jedná se tedy o negaci \b.

Příklad:

Zajímají-li vás všechny řádky, na nichž se písmeno ‚a‘ vyskytuje v roli jednopísmenné spojky, nasaďte

grep '\<a\>'

Totéž v Perlu (až na to, že se nevypisují jména souborů) by zajistil příkaz

perl -ne 'print if /\ba\b/'

Pokud se názvů souborů nehodláte vzdát, použijte

perl -ne 'print "$ARGV:$_" if /\ba\b/'

Shrnutí

výraz znamená
* libovolný počet opakování předchůdce
+ nebo \+ alespoň jeden výskyt předchůdce
? nebo \? nanejvýš jeden výskyt předchůdce
{min,max} nebo \{min,max\} alespoň min a nanejvýš max výskytů předchůdce
^ začátek řádku
$ konec řádku
\< nebo \b začátek slova
\> nebo \b konec slova
Našli jste v článku chybu?

28. 4. 2000 7:30

Pavel Trefny (neregistrovaný)

Bravo !!!!!!!! Neco takoveho uz jsem dlouho potreboval.

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Vitalia.cz: Pečete cukroví a zbyl vám bílek?

Pečete cukroví a zbyl vám bílek?

Root.cz: Vypadl Google a rozbilo se toho hodně

Vypadl Google a rozbilo se toho hodně

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Lupa.cz: Google měl výpadek, nejel Gmail ani YouTube

Google měl výpadek, nejel Gmail ani YouTube

Měšec.cz: Finančním poradcům hrozí vracení provizí

Finančním poradcům hrozí vracení provizí

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

DigiZone.cz: ČRa DVB-T2 ověřeno: Hisense a Sencor

ČRa DVB-T2 ověřeno: Hisense a Sencor

Vitalia.cz: Proč vás každý zubař posílá na dentální hygienu

Proč vás každý zubař posílá na dentální hygienu

DigiZone.cz: Flix TV má set-top box s HEVC

Flix TV má set-top box s HEVC

DigiZone.cz: ČT má dalšího zástupce v EBU

ČT má dalšího zástupce v EBU

DigiZone.cz: Sony KD-55XD8005 s Android 6.0

Sony KD-55XD8005 s Android 6.0

Vitalia.cz: Paštiky plné masa ho zatím neuživí

Paštiky plné masa ho zatím neuživí

Měšec.cz: Air Bank zruší TOP3 garanci a zdražuje kurzy

Air Bank zruší TOP3 garanci a zdražuje kurzy

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

Podnikatel.cz: Na poslední chvíli šokuje výjimkami v EET

Na poslední chvíli šokuje výjimkami v EET

Lupa.cz: Teletext je „internetem hipsterů“

Teletext je „internetem hipsterů“

Podnikatel.cz: 1. den EET? Problémy s pokladnami

1. den EET? Problémy s pokladnami

Vitalia.cz: Dáte si jahody s plísní?

Dáte si jahody s plísní?

DigiZone.cz: Rádio Šlágr má licenci pro digi vysílání

Rádio Šlágr má licenci pro digi vysílání