Go to the first, previous, next, last section, table of contents.


Reguláris kifejezések

A reguláris kifejezések, vagy regexp, szavak (betűk bizonyos halmazának) leírására alkalmasak. Mivel a reguláris kifejezések alapvetô részei az awk programozási nyelvnek, ezért egy önálló fejezetben tárgyaljuk ôket.

A `/' karakterek közé tett reguláris kifejezések szolgálnak awk mintaként és illeszkednek minden olyan sorra, amelyik az adott halmazhoz tartozik.

A legegyszerűbb reguláris kifejezés betűk és/vagy számok sorozata. Ezek a reguláris kifejezések minden olyan szóra illeszkednek, amelyek tartalmazzák az adott sorozatot. Így a `foo' reguláris kifejezés illeszkedik minden olyan szóra ami tartalmazza `foo'-t. Továbbá a /foo/ minta illeszkedik minden olyan bemeneti sorra amelyben a `foo' karaktersorozat, bárhol a sorban, elôfordul. Más reguláris kifejezések lehetôvé teszik bonyolultabb betűhalmazok definiálását.

Kezdetben a példák egyszerűek lesznek, de ahogy többet mondunk el arról, hogyan működnek a reguláris kifejezések, úgy egyre bonyolultabb példákat mutatunk.

Hogyan használjuk a reguláris kifejezéseket

Egy reguláris kifejezés mintaként használható ha `/' karakterek közé tesszük. Ebben az esetben egy reguláris kifejezés minden sor teljes szövegével összehasonlításra kerül. (Általában a szövegnek csak egy részéhez kell illeszkednie, hogy az összehasonlítás sikeres legyen.) Például ez a program kinyomtatja minden olyan sor második mezôjét, amely bárhol tartalmazza a `foo' karaktersorozatot:

$ awk '/foo/ { print $2 }' BBS-list
-| 555-1234
-| 555-6699
-| 555-6480
-| 555-2127

A reguláris kifejezések alkalmasak kifejezések keresésére is. Ebben az esetben a keresett kifejezést adja meg a reguláris kifejezés; ugyanakkor amiben keresünk nem feltétlenül a teljes sor. Két operátor, a `~' és a `!~', használható a keresésnél. Ezekkel az operátorokkal leírt kifejezések használhatók mint minták az if, while, for és a do kifejezésekben.

exp ~ /regexp/
A kifejezés igaz, ha a regexp kifejezés illeszkedik az exp kifejezésre (mint karaktersorozatra). Az alábbi példa kikeres minden olyan sort, amelyben az elsô mezô tartalmazza a nagy `J' betűt:
$ awk '$1 ~ /J/' inventory-shipped
-| Jan  13  25  15 115
-| Jun  31  42  75 492
-| Jul  24  34  67 436
-| Jan  21  36  64 620
Ez is ugyanazt csinálja:
awk '{ if ($1 ~ /J/) print }' inventory-shipped
exp !~ /regexp/
A kifejezés igaz, ha a regexp kifejezés nem illeszkedik az exp kifejezésre (mint karaktersorozatra). Az alábbi példa kiválaszt minden olyan sort, amelyben az elsô mezô nem tartalmazza a nagy `J' betűt:
$ awk '$1 !~ /J/' inventory-shipped
-| Feb  15  32  24 226
-| Mar  15  24  34 228
-| Apr  31  52  63 420
-| May  16  34  29 208
...

Amikor egy reguláris kifejezést `/' karakterek között írunk le, általában konstans reguláris kifejezésnek hívjuk, mint például az 5.27 egy szám konstans, és a "foo" egy szöveg konstans.

Escape szekvenciák

Néhány karaktert nem lehet közvetlenül használni egy szöveg konstansban ("foo") vagy konstans reguláris kifejezésben (/foo/), mivel speciális jelentésük van. Ezeket a karaktereket úgynevezett escape szekvenciákkal írhatjuk le; a nevüket onnan kapták, hogy egy `\' (escape) karakterrel kezdôdnek.

Az escape szekvenciák egyik használati lehetôsége, hogy a macskaköröm karaktert egy szövegben elhelyezzük. Egy önmagában álló macskaköröm karakter a szöveg lezárását jelentené, ezért kell a `\"' karaktersorozatot használni a szövegen belül. Például:

$ awk 'BEGIN { print "He said \"hi!\" to her." }'
-| He said "hi!" to her.

A `\' karakter maga is egy speciális karakter és nem szerepelhet önállóan a szövegben; a `\\' karaktersorozatot kell használni egy szövegben vagy egy reguláris kifejezésben. Például azt a szöveget, amely egy macskakörmöt és egy `\' karaktert tartalmaz, így kell leírni: "\"\\".

A `\' karakter másik alkalmazási köre a kinyomtathatatlan karakterek reprezentációja, mint például a tab és az új sor karakter. Bár semmi nincs ami megakadályozhatna, hogy ezeket a karaktereket közvetlenül használd egy szövegben vagy egy reguláris kifejezésben, de lehet hogy az összhatás elég csúnya lenne a használatukkal.

Az alábbiakban az awk-ban használható escape szekvenciák egy táblázatát adjuk meg. Hacsak nem írjuk másképp, ezek az escape szekvenciák mind a szövegekben, mind a reguláris kifejezésekben érvényesek.

\\
A `\' karakter maga.
\a
A figyelmeztetés (alert) karakter, Control-g, ASCII code 7 (BEL).
\b
Visszatörlés (backspace), Control-h, ASCII code 8 (BS).
\f
Lapdobás (formfeed) karakter, Control-l, ASCII code 12 (FF).
\n
Új sor karakter, Control-j, ASCII code 10 (LF).
\r
Kocsi vissza (carriage return) karakter, Control-m, ASCII code 13 (CR).
\t
Horizontális tab karakter, Control-i, ASCII code 9 (HT).
\v
Vertikális tab karakter, Control-k, ASCII code 11 (VT).
\nnn
Az oktális nnn szám egy, kettô vagy három jegyű. A számjegyek `0' és `7' közöttiek lehetnek. Például az ASCII ESC (escape) karakter kódja a `\033'.
\xhh...
A hexadecimális hh szám számjegyei a `0'-tól `9'-ig és vagy az `A'-tól `F'-ig vagy az `a'-tól `f'-ig terjedô karakterek lehetnek. Mint az ANSI C-ben, az escape szekvencia addig tart, ameddig érvényes hexadecimális számjegyek szerepelnek egymás után és az elsô érvénytelen karakternél véget ér. Ugyanakkor több mint két számjegy használata nem definiált viselkedést vált ki. (A `\x' escape szekvencia POSIX awk-ban nem megengedett.)
\/
Erre az escape szekvenciára csak reguláris kifejezéseknél lehet szükség. Olyan reguláris kifejezésnél kell használni, amikor maga a reguláris kifejezés is tartalmaz `/' karaktert. Mivel az önmagában álló `/' karakter a reguláris kifejezés végét jelölné, ezért kell az escape szekvenciát használni, hogy a reguláris kifejezés további részeit is figyelembe vegye az awk.
\"
Erre az escape szekvenciára csak szövegeknél lehet szükség. Ezt akkor kell használni, ha egy szövegben a macskaköröm karaktert is szeretnénk leírni. Mivel a szövegek macskakörmökkel vannak határolva, az escape szekvencát kell használni ahhoz, hogy az awk a szöveg további részét is figyelembe vegye.

A gawk-ban van még további két escape szekvencia, aminek speciális jelentése van a reguláris kifejezésekben, See section Csak a gawk által értelmezett reguláris kifejezés operátorok.

Mi történik ha egy szövegben olyan karakter elé teszel `\' karaktert amelyik nem szerepel a fenti táblázatban? A POSIX szabvány ezt az esetet tudatosan nem definiálja. Két lehetôség van:

Egy reguláris kifejezésben egy `\' karakter minden olyan karakter elôtt, amely nem szerepel a fenti táblázatban vagy section Csak a gawk által értelmezett reguláris kifejezés operátorok alatt, azt jelenti, hogy a karaktert nem szabad értelmezni mint reguláris kifejezés operátort. Például a /a\+b/ a `a+b' három karakterre illeszkedik.

A teljes hordozhatóság érdekében a `\' karaktert csak akkor használd más karakterek elôtt ha szükséges.

Érdekes kérdés lehet annak eldöntése is, hogy ha egy reguláris kifejezésekben használt operátort (metakaraktert) (see section Reguláris kifejezés operátorok) oktális vagy hexadecimális escape szekvenciával írunk le, akkor az awk mint egyszerű karakter vagy mint reguláris kifejezés operátor fogja azt kezelni.

Történelmileg, az ilyen karakterek mint egyszerű karakterek lesznek kezelve (s.s.). Ugyanakkor a POSIX szabvány azt írja elô, hogy mint reguláris kifejezés metakarakter kell ôket kezelni; a gawk pontosan így tesz. A gawk "compatibility" módban (see section Command Line Options) viszont mint egyszerű karakter kezeli az így leírt escape szekvenciákat, például /a\52b/ megegyezik a /a\*b/ mintával.

Összefoglalva:

  1. A fenti táblázatban szereplô összes escape szekvencia kerül elôször feldolgozásra a szövegekben és reguláris kifejezésekben, amint az awk beolvasta.
  2. A gawk feldolgozza a konstans és dinamikus reguláris kifejezéseket (see section Dinamikus reguláris kifejezések használata) a speciális operátorok számára (section Csak a gawk által értelmezett reguláris kifejezés operátorok).
  3. Bármely karakter elôtt elôforduló `\' karakter esetén a karaktert nem kezeli speciálisan, hanem magát a karaktert használja.

Reguláris kifejezés operátorok

Az egyszerű reguláris kifejezéseket az úgynevezett reguláris kifejezés operátorokkal vagy metakarakterekkel kombinálva összetettebb és sokoldalúbb mintákat lehet készíteni.

A fent bemutatott escape szekvenciák, section Escape szekvenciák, érvényesek a reguláris kifejezésekben is. A reguláris kifejezések feldolgozása során az awk elôször ezeket a karakter sorozatokat konvertálja az aktuális karakterré.

Itt közöljük a metakarakterek táblázatát. Minden olyan karakter, amely nem escape szekvencia és nem szerepel az alábbi táblázatban egyszerűen önmagát jelenti.

\
Ezzel a karakterrel elnyomható a követô karakter speciális jelentése a mintában. Például a
\$
a `$' karakterre illeszkedik.
^
Ez a karakter a sor elejére illeszkedik. Például:
^@chapter
illeszkedik a `@chapter'-re egy sor elején, ami alkalmas a fejezetek kezdetének megtalálására egy Texinfo file-ban. A `^' karaktert "horgonynak" is szokták nevezni, mivel a használatával a minta csak a sor elejére illeszkedik, oda horgonyozza a mintát. Fontos tudni, hogy a `^' karakter nem illeszkedik egy szövegben elrejtett új sor kezdetére, így az alábbi feltétel hamis:
if ("line1\nLINE 2" ~ /^L/) ...
$
Hasonló a `^' karakterhez, de a sor végéhez illeszkedik, például:
p$
illeszkedik azokra a sorokra, amelyek `p'-vel végzôdnek. A `$' karakter szintén egy "horgony", és ahogy a `^' karakter úgy a `$' karakter sem illeszkedik az elrejtett új sor végére, tehát az alábbi feltétel is hamis:
if ("line1\nLINE 2" ~ /1$/) ...
.
A pont karakter egyetlen (bármely) karakterre illeszkedik, még az új sor karakterre is. Például:
.P
illeszkedik egy olyan karakterre, amit egy `P' követ a szövegben. Összeállíthatunk olyan reguláris kifejezést is, mint `U.A', amely illeszkedik bármely három karakterre, ami `U' karakterrel kezdôdik és az `A' karakterrel végzôdik. Szigorú POSIX módban (see section Command Line Options), a `.' karakter nem illeszkedik a NUL karakterre. Ennek a karakternek minden bitje zérus, egyébként a NUL karakter is olyan, mint bármely más karakter. Léteznek olyan awk verziók is, amelyek nem képesek a NUL karaktert keresni.
[...]
A karakter lista illeszkedik bármelyik karakterre, de csak egyre, ami szerepel a szögletes zárójelek között. Például az
[MVX]
illeszkedik az `M', `V' vagy `X' karakterek bármelyikére a szövegben. Karakter tartományok esetén a mínusz karaktert kell használni a kezdô- és a végkarakter között, például a
[0-9]
illeszkedik bármelyik számjegyre. Több tartomány is megadható. Pl. a [A-Za-z0-9] listával írhatjuk le az összes "alfanumerikus" karaktert. Ahhoz, hogy a `\', `]', `-' vagy `^' karakterek valamelyikét figyelembe vehessük a szögletes zárójelek között a `\' karaktert kell eléjük tenni, például:
[d\]]
illeszkedik vagy a `d' vagy a `]' karakterre. A `\' ilyetén használata a karakter listákban kompatíbilis más awk implementációkkal, és a POSIX szabvány is a fenti megoldást írja elô. A POSIX által definiált "Kiterjesztett Reguláris Kifejezések" (KRK) csak egy részhalmaza az awk reguláris kifejezéseinek. A POSIX "Kiterjesztett Reguláris Kifejezések" a hagyományos egrep segédprogram által elfogadott reguláris kifejezéseken alapulnak. A karakterosztályok nem olyan régen lettek bevezetve a POSIX szabványba. A karakterosztály azon karakterlisták speciális leírása, amelyek valamilyen értelemben egyedi tulajdonsággal rendelkeznek, de az aktuális karakterek országonként és/vagy ábécénként eltérhetnek. Például az ábécé betűi mások az USA-ban, mint Franciaországban. A karakter osztályok csak a karakter listák szögletes zárójelein belül érvényesek. A karakter osztály a `[:' karakterekkel kedôdik, amit az osztályt leíró kulcsszó és a záró `:]' karakterek követnek. A POSIX szabványban definiált karakter osztályok az alábbiak.
[:alnum:]
Alfanumerikus karakterek.
[:alpha:]
Az ábécé betűi.
[:blank:]
Szóköz és tabulátor karakter.
[:cntrl:]
Vezérlôkarakterek.
[:digit:]
Számjegyek.
[:graph:]
Azon karakterek, amelyek nyomtathatóak és láthatóak. (A szóköz karakter nyomtatható, de nem látható, míg az `a' karakter mindkettô.)
[:lower:]
Az ábécé kisbetűi.
[:print:]
Nyomtatható karakterek (a nem vezérlôkarakterek).
[:punct:]
Írásjelek (nem az ábécé betűi, nem számjegyek, nem vezérlôkarakterek és nem szóköz, tabulátor).
[:space:]
Szóköz, tabulátor, lapdobás karakterek, hogy csak néhányat említsünk.
[:upper:]
Az ábécé nagybetűi.
[:xdigit:]
Hexadecimális számjegyek.
A POSIX szabvány kiadása elôtt az alfanumerikus karakterek kereséséhez az /[A-Za-z0-9]/ mintát kellett használni. Ha az ábécében más betű is szerepel (pl. ékezetes karakterek) azokat a minta nem veszi észre. A POSIX karakter osztályok használatával csak a /[[:alnum:]]/ mintát kell leírni, hogy az ábécé összes betűjét felismerje a keresésnél. Van két további speciális karaktersorozat, ami a karakterlistákon belül elôfordulhat. Az egyik azokat a nem ASCII karaktereket reprezentálja, amelyeket csak több mint egy karakterrel írhatunk le (több karakterrel leírható szimbólumok), a másik azokat a karaktereket írja le, amelyeknek nem csak egy megjelenési formája van, de pl. egy rendezés során azonosnak kell ôket tekinteni. (Például a franciában az egyszerű "e" és az "`e" karakterek megegyeznek egy rendezés során.)
Több karakterrel leírható szimbólumok
Ezeket az elemeket a `[.' és a `.]' karakterek között kell leírni. Például, ha `ch' egy ilyen elem, akkor a [[.ch.]] reguláris kifejezés illeszkedni fog az adott szimbólumra, míg a [ch] vagy a `c' vagy a `h' karakterre.
Azonossági osztályok
Az azonossági osztály egy speciális név azokra a karakterekre amelyek a helyi ábécé szerint azonosak, de a megjelenési formájuk különbözô. A nevet a `[=' és a `=]' jelek közé kell tenni. Például az `e' név jelentheti a "e," "`e" és "é." karaktereket. Ebben az esetben a [[=e=]] illeszkedhet a `e', `é' vagy ``e' karakterek bármelyikére.
Ezek az osztályok a nem angol nyelvterületeken lehetnek nagyon hasznosak. Figyelem: A gawk jelenleg a reguláris kifejezések olyan implementációját használja, amelyik csak a POSIX szabványban rögzített karakter osztályokat ismeri fel, és az utóbbi két osztályt nem.
[^ ...]
A komplemens karakter listában az elsô karakter a `[' után a `^' karakter kell legyen. A lista illeszkedik minden olyan karakterre, amelyik nem szerepel a szögletes zárójelek között. Például:
[^0-9]
illeszkedik minden olyan karakterre, amelyik nem számjegy.
|
A alternatív operátor választási lehetôséget ad, például:
^P|[0-9]
illeszkedik vagy a `^P'-re vagy a `[0-9]', ami azt jelenti, hogy a minta illeszkedik bármely sorra, ami `P' karakterrel kezdôdik, vagy tartalmaz egy számjegyet. Az operátor a lehetô legnagyobb reguláris kifejezést használja a karakter két oldaláról, vagy más szavakkal a `|' operátornak van a legalacsonyabb precedenciája a reguláris kifejezések között.
(...)
A zárójelek a reguláris kifejezések csoportosítására alkalmasak, ugyanúgy mint a matematikában. Az alternatív operátor körüli reguláris kifejezés meghatározására is alkalmas, például a `@(samp|code)\{[^}]+\}' kifejezés illeszkedik a `@code{foo}' és a `@samp{bar}' szövegre is.
*
Ez a szimbólum azt jelenti, hogy a megelôzô reguláris kifejezést annyiszor kell ismételni, ha szükséges, amíg egyezést nem talál. Például:
ph*
esetén a `*' szimbólumot a megelôzô `h' karakterre (mint reguláris kifejezésre) alkalmazva egy olyan mintát keres, amiben szerepel egy `p' majd akárhány `h' karakter. Ez a minta az önmagában álló `p' karakterre is illeszkedik. A `*' szimbólum a lehetô legrövidebb, megelôzô reguláris kifejezésre lesz alkalmazva (hosszabb reguláris kifejezés esetén zárójelet kell használni), és annyi ismétlést próbál találni, amennyi lehetséges. Például:
awk '/\(c[ad][ad]*r x\)/ { print }' sample
kinyomtat a `sample' file-ból minden olyan sort, amely tartalmazza a `(car x)', `(cdr x)', `(cadr x)', stb. kifejezések valamelyikét. Fontos a `\' karakter használata a zárójelek elôtt.
+
A `+' szimbólum hasonló a `*' szimbólumhoz, de a megelôzô reguláris kifejezést legalább egyszer meg kell találnia szövegben. Így a
wh+y
illeszkedik a `why' és a `whhy' szavakra, de a `wy' szóra nem. Ugyanakkor a `wh*y' minta illeszkedik mind a három szóra. A fenti példa tehát így írható le egyszerűbben:
awk '/\(c[ad]+r x\)/ { print }' sample
?
A szimbólum hasonlít a `*' szimbólumra, de a megelôzô kifejezés csak egyszer vagy egyszer sem fordulhat elô a szövegben, például:
fe?d
illeszkedik a `fed' és `fd' szavakra, de semmi másra nem.
{n}
{n,}
{n,m}
Egy vagy két szám kapcsos zárójelek között írja le az intervallum kifejezéseket. Ha csak egy szám szerepel a kapcsos zárójelek között, akkor a megelôzô reguláris kifejezést pontosan n-szer kell ismételni az illeszkedéshez. Ha két szám szerepel kapcsos zárójelek között, vesszôvel elválasztva, akkor a megelôzô reguláris kifejezést n és m közötti alkalommal kell megismételni az illeszkedéshez. Ha csak egy szám és utána egy vesszô van kapcsos zárójelek között, akkor legalább n-szer kell megismételni a megelôzô reguláris kifejezést az illeszkedéshez.
wh{3}y
illeszkedik a `whhhy' szóra, de sem a `why' sem a `whhhhy' szavakra nem.
wh{3,5}y
illeszkedik a `whhhy', `whhhhy' és a `whhhhhy' szavak valamelyikére, de másra nem.
wh{2,}y
illeszkedik a `whhy', `whhhy', stb. szavakra.
Nem voltak intervallum kifejezések az eredeti awk-ban, de a POSIX szabvány azért vezette be ôket, hogy az awk és az egrep következetesen legyenek definiálva. Mindemellett régi programok használhatják a `{' és a `}' karaktereket reguláris kifejezésekben, ezért a gawk alapesetben nem engedi meg intervallum kifejezések használatát a reguláris kifejezésekben. Ha `--posix' vagy a `--re-interval' parancssori opció (see section Command Line Options) definiálva van, intervallum kifejezések megengedettek a reguláris kifejezésekben.

A reguláris kifejezésekben a `*', `+', `?' operátoroknak és a kapcsos zárójeleknek van a legmagasabb precedenciájuk, majd ezt követi az összefűzés operátor. A legalacsonyabb precedenciája a `|' operátornak van. Mint a matematikában, a zárójelekkel megváltoztatható az operátorok kiértékelési sorrendje.

A karakterosztályok és intervallum operátorok használata nem engedélyezett ha a gawk "compatibility" módban (see section Command Line Options) fut.

A következô bekezdés tárgyalja a GNU specifikus reguláris kifejezés operátorokat, ill. további részleteket ad arról, hogy különbözô parancssori opciók esetén a gawk hogyan értelmezi a karaktereket a reguláris kifejezésekben.

Csak a gawk által értelmezett reguláris kifejezés operátorok

A reguláris kifejezéseket használó GNU software-ek néhány extra operátort is ismernek, amelyeket ebben a bekezdésben tárgyalunk. Ezek az operátorok jelen esetben csak a gawk-ban találhatók meg, és más awk implementációkkal nem használhatók.

Ezen operátorok legtöbbje szavak illesztésére alkalmas. Jelen esetben egy szót betűk, számjegyek és a `_' karakter sorozataként definiálhatunk.

\w
Ez az operátor illeszkedik a szavakat felépítô bármely karakterre, például betűk, számjegyek és az aláhúzás karakterre. Lényegében az alábbi kifejezés rövidítése [[:alnum:]_].
\W
Ez az operátor illeszkedik a szavakat fel nem építô karakterekre. Röviden [^[:alnum:]_].
\<
Ez az operátor illeszkedik egy szó elején elôforduló üres karaktersorozatra. Például, az /\<away/ minta illeszkedik a `away' szóra, de nem a `stowaway' szóra.
\>
Ez az operátor illeszkedik egy szó végén elôforduló üres karaktersorozatra. Például a /stow\>/ minta illeszkedik a `stow' szóra, de nem a `stowaway' szóra.
\y
Ez az operátor illeszkedik vagy a szó elején vagy a végén elhelyezkedô üres karaktersorozatra. Például a `\yballs?\y' illeszkedik vagy a `ball' vagy a `balls' különálló szóra.
\B
Ez az operátor illeszkedik a szó közben elôforduló üres karakter sorozatra. Más szavakkal, a `\B' operátor illeszkedik a szavakat alkotó karakterek közti üres karaktersorozatra. Például, a /\Brat\B/ minta illeszkedik a `crate' szóra, de nem illeszkedik a `dirty rat' kifejezésre. A `\B' operátor lényegében a `\y' operátor ellentéte.

Más GNU software-ekben a szó határoló operátor a `\b', de ez összeütközésben van az awk nyelv definíciójával, ahol a `\b' a törlés (backspace) karakter, így a gawk egy másik operátort használ.

Megoldás lenne ha a GNU operátoroknál két `\' jelet kellene használni, de ez valószínűleg túl zavaró lenne, ezért használja a gawk a `\y' operátort, ami talán két rossz megoldás közül a kevésbé rossz.

A különbözô parancssori opciók (see section Command Line Options) befolyásolják a gawk interpretert, hogy hogyan értelmezze a reguláris kifejezésekben elôforduló karaktereket:

nincs opció megadva
Alapesetben a gawk biztosítja az POSIX reguláris kifejezés operátorok és a GNU operátorok, section Reguláris kifejezés operátorok, használatát, de intervallum kifejezéseket nem lehet használni.
--posix
Csak a POSIX operátorok engedélyezettek, a GNU operátorokat nem ismeri fel (így a `\w' megfelel a `w' betűnek). Intervallum operátorokat lehet használni.
--traditional
Hagyományos Unix awk reguláris kifejezéseket lehet csak használni. A GNU operátorok, intervallum kifejezések és karakterosztályok ([[:alnum:]] és így tovább) nem állnak rendelkezésre. Oktálisan vagy hexadecimálisan leírt karakterek önmagukat jelentik, még akkor is ha reguláris kifejezés metakarakterek lennének normális esetben.
--re-interval
Intervallum kifejezések használatát engedélyezi, még akkor is ha a `--traditional' opció is meg lett adva.

Kis- és nagybetűk az illesztésekben

Lényeges, hogy a reguláris kifejezésekben kisbetűt vagy nagybetűt használunk a normál (nem meta-) karakterek illesztésénél. Így a `w' karakter egy reguláris kifejezésben csak a `w' kisbetűre fog illeszkedni a `W'-re nem.

A legegyszerűbb módja a kisbetűs, nagybetűs írásmódtól független illesztésnek a karakterlisták használata: `[Ww]'. Ugyanakkor ez elég kényelmetlen lehet ha sokat kell használni, ráadásul a reguláris kifejezéseket is elbonyolítja. Két lehetôség van a probléma megoldására.

Az elsô esetben, a program egy adott pontján az adatot átalakítjuk csak kisbetűs vagy csak nagybetűs írásmódba a tolower vagy a toupper beépített függvényekkel (amiket még eddig nem tárgyaltunk, see section Szövegmanipuláló beépített függvények). Például:

tolower($1) ~ /foo/  { ... }

az illesztés elôtt az elsô mezô minden karakterét átalakítja kisbetűvé. Ez bármely POSIX kompatíbilis awk implementációban működni fog.

A másik módszer csak gawk-ban használható, amikor is az IGNORECASE beépített változót át kell állítani egy nem zérus értékre. Amikor az IGNORECASE változó nem zérus, minden reguláris kifejezés és szöveg művelet esetén figyelmen kívül hagyja a kisbetű-nagybetű különbséget. A változó állítása a programon belül befolyásolja, hogy mely részeknél tegyen különbséget a kis- és nagybetűk között. Mivel kezdetben minden változó zérus értéket kap, így az IGNORECASE változó is, ezért tesz különbséget a kis- és nagybetűk között alapesetben.

x = "aB"
if (x ~ /ab/) ...   # ez feltétel hamis

IGNORECASE = 1
if (x ~ /ab/) ...   # most már sikeres lesz

Általában az IGNORECASE változó nem használható arra, hogy csak egyes szabályok esetén tegyen különbséget kis- és nagybetűk között és másoknál pedig nem, mivel nincs arra lehetôség hogy csak egy szabályra vagy mintára állítsuk be. (5) A megoldást vagy a karakterlisták vagy a tolower beépített függvény adja. Az IGNORECASE változót lényegében az összes szabályra érdemes be- vagy kikapcsolni.

Az IGNORECASE változó beállítható a parancssorból vagy a BEGIN szabályban (see section Other Command Line Arguments; és see section Kezdô és lezáró tevékenységek) Az IGNORECASE változó parancssorból történô beállítása esetén a program szerkesztése nélkül biztosítható, hogy a program nem fog különbséget tenni a kis- és nagybetűk között.

A gawk 3.0-ás verziója elôtt az IGNORECASE változó értéke csak a reguláris kifejezésekkel végzett műveleteket érintette, és nem volt hatással a `==', `!=' és hozzájuk hasonló szövegösszehasonlító operátorokra. A 3.0-ás verziótól kezdve mind a reguláris kifejezésekkel, mind a szövegekkel végzett összehasonlítás esetén az IGNORECASE változó értéke hatással van a végeredményre.

A gawk 3.0-ás verziójától kezdve a kis- és nagybetűs karakterek azonossága az ISO-8859-1 (ISO Latin-1) karakterkészlet alapján dôl el. Az eredeti 128 ASCII karakterkészlet csak egy részhalmaza ennek a karakterkészletnek, és az ISO-8859-1 segítségével több európai nyelv karakterei is használhatók.

Az IGNORECASE változó értéke nem számít ha a gawk "compatibility" módban fut (see section Command Line Options). Ebben az esetben a kis- és nagybetűk közötti különbség mindig fontos.

Mennyi szöveg illeszkedik?

Vegyük a következô példát:

echo aaaabcd | awk '{ sub(/a+/, "<A>"); print }'

Ez a példa a sub függvényt használja, (amit eddig még nem tárgyaltunk, see section Szövegmanipuláló beépített függvények) hogy a bemeneti soron módosítást végezzen. A /a+/ reguláris kifejezés "egy vagy több `a' karakterre illeszkedik" és amire lecserélnénk az az `<A>' szöveg.

A bemenet négy `a' karaktert tartalmaz. Mi lesz az eredmény? Más szavakkal, mennyi az "egy vagy több" -- az awk kettô, három vagy négy `a' karakterre fog illeszteni?

A válasz az, hogy az awk (és a POSIX is) mindig a lehetô leghosszabb bemeneti karaktersorozatot fogja illeszteni. Így, ebben a példában, elsôre mind a négy karakterre illeszkedik a minta és egyszerre cseréli le a `<A>' kifejezésre.

$ echo aaaabcd | awk '{ sub(/a+/, "<A>"); print }'
-| <A>bcd

Egyszerű illeszkedik/nem illeszkedik teszteknél ez nem olyan fontos, de amikor regexp alapú mezô és rekord feldarabolást (see section Hogyan történik a feldarabolás rekordokra és see section Hogyan történik a mezôelválasztás) kell csinálni és a match, sub, gsub és a gensub függvényeket kell használni, akkor ez nagyon fontossá válhat.

Dinamikus reguláris kifejezések használata

A `~' vagy `!~' operátorok esetén nem kötelezô hogy a jobb oldalon egy reguláris kifejezés konstans álljon (valamilyen szöveg `/' jelek között), hanem bármilyen kifejezés állhat ott. Az awk a kifejezést kiértékeli és ha szükséges átalakítja szöveggé; a szöveg tartalmát használja, mint reguláris kifejezés. Az ilyen reguláris kifejezéseket dinamikus reguláris kifejezésnek hívják. Például:

BEGIN { identifier_regexp = "[A-Za-z_][A-Za-z_0-9]+" }
$0 ~ identifier_regexp    { print }

beállítja a identifier_regexp változót egy olyan reguláris kifejezésre, ami az awk változók neveire illeszkedik, majd megpróbálja illeszteni a bemeneti adatokra.

Figyelem: Amikor a `~' és a `!~' operátorokat használod jelentôs különbség van a `/' jelek között megadott regexp konstansok és a macskakörmök között megadott szöveg konstansok között. Amikor a szöveg konstanst használod, tudnod kell, hogy a szöveg kétszer lesz feldolgozva; egyszer amikor az awk beolvassa a programodat, másodszor amikor a bal oldalon levô szöveget megpróbálja illeszteni a jobb oldali mintához. Ez igaz minden szöveg tartalmú kifejezésre (így a fenti identifier_regexp változóra is) és nem csak a szöveg konstansokra.

Miért fontos, hogy a szöveg kétszer lesz feldolgozva ? A válasz az escape szekvenciákat érinti és különösen a `\' karaktert. Ahhoz, hogy a `\' karaktert egy reguláris kifejezésben használhassuk mint egyszerű karaktert, a `\' karaktert kétszer kell leírni.

Például a /\*/ kifejezés egy olyan regexp konstans ami megfelel az egyszerű `*' karakternek. Csak egy `\' karakter kell! Ugyanezt megcsinálni egy szöveg konstans esetén így lehet, "\\*". Az elsô `\' védi a másodikat és valójában csak két karakter van a szövegben a `\' és a `*' karakterek.

Tehát ha regexp és szöveg konstansok is használhatók reguláris kifejezések leírására, melyiket használjuk? A "regexp konstansokat", több okból is.

  1. A szöveg konstansokat bonyolultabb írni és nehezebb olvasni is. Ha regexp konstansokat használsz kevesebbet hibázhatsz. Gyakori hiba, hogy az emberek nem értik a két konstans közötti különbséget.
  2. A regexp konstansok használata hatékonyabb is: az awk a reguláris kifejezéseket egy belsô struktúrában tárolja, így a mintaillesztés gyorsabb. Amikor szöveg konstanst használsz, az awk-nak elôször át kell alakítania a kifejezést ebbe a belsô struktúrába, és csak utána tud mintaillesztést csinálni.
  3. A regexp-ek használata egy szebb programozási stílus; világosan mutatja, hogy egy reguláris kifejezés illesztést akartál csinálni.


Go to the first, previous, next, last section, table of contents.