Wyrażenie regularne (regular expression), lub regexp, jest
metodą opisu zbioru łańcuchów. Ponieważ wyrażenia regularne są tak
podstawową częścią programowania w języku awk, ich format
i stosowanie wymagają odrębnego rozdziału.
Wyrażenie regularne ujęte w ukośniki (`/') jest wzorcem
awk, dopasowującym każdy rekord wejściowy, którego tekst należy do
tego zbioru.
Najprostszym wyrażeniem regularnym jest ciąg liter, cyfr lub
zarówno liter jak cyfr. Takie wyrażenie regularne dopasowuje dowolny łańcuch
zawierający ten ciąg. Zatem, wyrażenie regularne `foo' dopasowuje
dowolny łańcuch zawierający `foo'. Stąd też, wzorzec /foo/
dopasowuje dowolny rekord wejściowy zawierający trzy znaki `foo',
w dowolnym miejscu rekordu. Inne rodzaje wyrażeń regularnych pozwalają
na określanie bardziej skomplikowanych klas łańcuchów.
Początkowo, przykłady będą proste. Kiedy wyjaśnimy więcej na temat działania wyrażeń regularnych, przedstawimy bardziej skomplikowane
Przez umieszczenie go w ukośnikach wyrażenie regularne może być używane jako wzorzec. Jest ono wówczas sprawdzane z całym tekstem każdego rekordu. (Normalnie, wystarczy mu dopasowanie tylko części tekstu, by sprawdzenie się powiodło.) To, na przykład, wypisuje drugie pole z każdego rekordu, który gdziekolwiek zawiera trzy znaki `foo':
$ awk '/foo/ { print $2 }' BBS-list
-| 555-1234
-| 555-6699
-| 555-6480
-| 555-2127
Wyrażeń regularnych można też używać w wyrażeniach dopasowania. Wyrażenia
takie umożliwiają podanie łańcucha, który ma być dopasowywany; nie musi to
być cały bieżący rekord wejściowy. Porównań wyrażeń regularnych dokonują
dwa operatory, `~' i `!~'. Wyrażenia wykorzystujące te
operatory mogą być używane jako wzorce lub w instrukcjach if,
while, for i do.
wyr ~ /regexp/
$ awk '$1 ~ /J/' inventory-shipped -| Jan 13 25 15 115 -| Jun 31 42 75 492 -| Jul 24 34 67 436 -| Jan 21 36 64 620To samo robi to:
awk '{ if ($1 ~ /J/) print }' inventory-shipped
wyr !~ /regexp/
$ 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 ...
Gdy wyrażenie regularne zapisane jest w ukośnikach, jak /foo/,
nazywamy je stałą regexp (wyrażeniem regularnym stałym), podobnie jak
5.27 jest stałą liczbową, a "foo" jest stałą łańcuchową.
Pewne znaki nie mogą być zawarte dosłownie w stałych łańcuchowych
("foo") czy stałych wyrażeniach regularnych (/foo/). Zamiast
tego są reprezentowane przez sekwencje specjalne (escape sequences),
będące ciągami znaków rozpoczynającymi się od odwrotnego ukośnika (`\').
Jednym z zastosowań sekwencji specjalnych jest włączanie znaku cudzysłowu do stałej łańcuchowej. Ponieważ zwykły cudzysłów kończyłby łańcuch, musimy użyć `\"' do przedstawienia rzeczywistego znaku cudzysłowu jako części łańcucha. Na przykład:
$ awk 'BEGIN { print "He said \"hi!\" to her." }'
-| He said "hi!" to her.
Sam znak odwrotnego ukośnika jest innym znakiem, który nie może dołączany
normalnie; piszemy `\\' by umieścić pojedynczy odwrotny ukośnik
w łańcuchu lub wyrażeniu regularnym. Zatem, łańcuch, którego zawartością
są dwa znaki: `"' i `\', musi zostać zapisany "\"\\".
Innym zastosowaniem odwrotnego ukośnika jest reprezentacja znaków takich jak tabulacja czy znak nowej linii. Mimo, że nic nie powstrzymuje cię przed wprowadzeniem większości znaków niedrukowalnych do stałej łańcuchowej czy regexp, mogą one wyglądać paskudnie.
A oto tabela wszystkich sekwencji specjalnych używanych w awk, razem
z tym, co oznaczają. Wszystkie te sekwencje mają zastosowanie zarówno
do stałych łańcuchowych jak i do stałych regexp, chyba że powiedziano
inaczej.
\\
\a
\b
\f
\n
\r
\t
\v
\nnn
\xhh...
awk.)
\/
awk, by przetwarzał resztę wyrażenia.
\"
awk, by przetwarzał resztę łańcucha.
W gawk istnieją dwie dodatkowe sekwencje specjalne, rozpoczynające
się odwrotnym ukośnikiem i mające specjalne znaczenie w wyrażeniach
regularnych.
Zob. 4.4. Dodatkowe operatory regexp w gawk.
Co się stanie, jeśli w stałej łańcuchowej umieścimy odwrotny ukośnik
przed czymś, co nie jest jednym ze znaków wyszczególnionych powyżej?
POSIX awk celowo pozostawia ten przypadek niezdefiniowany.
Są dwie możliwości.
awk, jak
i gawk. Na przykład, "a\qc" jest tym samym co "aqc".
awk. W takich implementacjach, "a\qc" jest
tym samym, co napisanie "a\\qc".
W wyrażeniu regularnym, odwrotny ukośnik przed znakiem nie znajdującym się
w powyższej tablicy, i nie wymienionym
w 4.4. Dodatkowe operatory regexp w gawk,
oznacza, że kolejny znak powinien być brany dosłownie, nawet jeśli normalnie byłby on
operatorem wyrażeń regularnych. Np., /a\+b/ dopasowuje trzy znaki
`a+b'.
Dla zapewnienia pełnej przenośności, nie stosuj odwrotnego ukośnika przed żadnym ze znaków nie podanych w tablicy powyżej.
Nasuwa się inna interesująca kwestia.
Załóżmy, że używamy sekwencji specjalnej z wartością ósemkową lub
szesnastkową do reprezentacji metaznaku wyrażeń regularnych
(zob. 4.3. Operatory wyrażeń regularnych). Czy awk
potraktuje ten znak jako znak dosłowny, czy też jako operator wyrażeń
regularnych?
Okazuje się, że historycznie takie znaki były brane dosłownie (c.k.).
Jednak standard POSIX wskazuje, że powinny być one traktowane jak
rzeczywiste metaznaki, i tak to robi gawk. Jednak, w trybie
zgodności (zob. 14.1. Opcje wiersza poleceń), gawk traktuje
znaki reprezentowane przez ósemkowe lub szesnastkowe sekwencje specjalne
dosłownie, gdy są one stosowane w stałych regexp. Zatem, /a\52b/
jest równoważne /a\*b/.
Podsumowując:
awk.
gawk przetwarza zarówno stałe wyrażenia regularne jak i
dynamiczne wyrażenia regularne (zob. 4.7. Stosowanie dynamicznych wyrażeń regularnych),
specjalne operatory podano
w 4.4. Dodatkowe operatory regexp w gawk.
Wyrażenia regularne można łączyć za pomocą niżej opisanych znaków, zwanych operatorami wyrażeń regularnych, lub metaznakami, zwiększając moc i wszechstronność wyrażeń regularnych.
Wewnątrz wyrażeń regularnych poprawne są sekwencje specjalne opisane powyżej w 4.2. Sekwencje specjalne. Są one wprowadzane przez `\'. Ich rozpoznawanie i przekształcanie na odpowiadające im rzeczywiste znaki jest pierwszym krokiem przetwarzania wyrażeń regularnych.
A oto tabela metaznaków. Wszystkie znaki nie będące sekwencjami specjalnymi i nie podane w tej tabeli znaczą same siebie.
\
\$dopasowuje znak `$'.
^
^@chapterdopasowuje `@chapter' na początku łańcucha, i może być wykorzystane do identyfikacji rozdziałów w plikach źródłowych Texinfo. `^' znany jest jako kotwica, gdyż zaczepia wzorzec tak, by pasował tylko na początku łańcucha. Należy zdawać sobie sprawę z tego, że `^' nie dopasowuje początku wiersza zawartego w łańcuchu. W tym przykładzie warunek nie jest prawdziwy:
if ("wiersz1\nWIERSZ 2" ~ /^W/) ...
$
p$dopasowuje rekord kończący się na `p'. `$' jest również kotwicą, i również nie dopasowuje końca wiersza zawartego wewnątrz łańcucha. W tym przykładzie warunek nie jest prawdziwy:
if ("wiersz1\nWIERSZ 2" ~ /1$/) ...
.
.Pdopasowuje w łańcuchu dowolny pojedynczy znak, po którym następuje `P'. Posługując się konkatenacją (łączeniem) można tworzyć takie wyrażenia regularne jak np. `U.A', dopasowujące dowolną trzyznakową sekwencję rozpoczynającą się od `U' a kończącą na `A'. W trybie ścisłej zgodności z POSIX (zob. 14.1. Opcje wiersza poleceń), `.' nie dopasowuje znaku NUL, będącego znakiem o wszystkich bitach równych zero. Bez ścisłej zgodności NUL jest po prostu znakiem jak każdy inny. Inne wersje
awk mogą nie umieć dopasować
znaku NUL.
[...]
[MVX]dopasowuje w łańcuchu dowolny ze znaków `M', `V' albo `X'. Zakresy znaków wskazywane są przez użycie myślnika pomiędzy znakiem rozpoczynającym a kończącym zakres, i ujęcie całości w nawiasy kwadratowe. Na przykład:
[0-9]dopasowuje dowolną cyfrę. Dopuszcza się wielokrotne zakresy. Np. lista
[A-Za-z0-9] jest
popularnym sposobem wyrażania pojęcia "wszystkich znaków alfanumerycznych"
[tłum.: w alfabecie łacińskim].
Chcąc w liście ująć jeden ze znaków `\', `]', `-' lub `^'
należy postawić przed nim `\'. Na przykład:
[d\]]dopasowuje albo `d' albo `]'. Takie traktowanie odwrotnego ukośnika `\' w liście znaków jest zgodne z innymi implementacjami
awk, jest też wymagane przez POSIX.
Wyrażenia regularne w awk są nadzbiorem specyfikacji
POSIX opisującej rozszerzone wyrażenia regularne (Extended Regular
Expressions, EREs). ERE POSIX-a oparte są na wyrażeniach regularnych
akceptowanych przez tradycyjne narzędzie egrep.
Klasy znaków są nową cechą wprowadzoną w standardzie POSIX. Klasa
znaków jest specjalną notacją opisującą listy znaków mających specyficzne
właściwości, gdzie jednak same konkretne znaki mogą zmieniać się w
zależności od kraju i/lub zestawu znaków. Na przykład, pojęcie tego, co
jest znakiem alfabetu, jest różne w USA i we Francji.
Klasa znaków jest poprawna wyłącznie wewnątrz nawiasów kwadratowych
listy znaków w wyrażeniu regularnym. Klasy znaków składają się z `[:',
słowa kluczowego oznaczającego klasę, i `:]'. Oto klasy znaków
zdefiniowane przez standard POSIX.
[:alnum:]
[:alpha:]
[:blank:]
[:cntrl:]
[:digit:]
[:graph:]
[:lower:]
[:print:]
[:punct:]
[:space:]
[:upper:]
[:xdigit:]
/[A-Za-z0-9]/. Jeżeli wykorzystywany zestaw
znaków miał inne znaki alfabetu, to powyższe by ich nie dopasowywało.
Za pomocą POSIX-owych klas znaków można napisać /[[:alnum:]]/,
i będzie to dopasowywać wszystkie znaki literowe i cyfrowe naszego
zestawu znaków.
W listach znaków mogą pojawić się dwie dodatkowe specjalne sekwencje.
Mają one zastosowanie w zestawach znaków innych niż ASCII,
mających pojedyncze symbole (zwane elementami porządkowania,
collating elements) reprezentowane przez więcej niż jeden znak, lub
też kilka znaków, które są sobie równoważne przy porządkowaniu czy
sortowaniu. (Np. we francuskim zwykłe "e" i z akcentem grave
"`e" są równoważne.)
[[.ch.]] jest wyrażeniem regularnym
dopasowującym ten element porządkowania, podczas gdy [ch] jest
wyrażeniem regularnym dopasowującym albo `c' albo `h'.
[[=e]] jest wyrażeniem regularnym dopasowującym dowolny ze znaków
`e', `'e' lub ``e'.
gawk
do dopasowywania wyrażeń regularnych rozpoznają obecnie jedynie POSIX-owe
klasy znaków; nie rozpoznają symboli porządkowania ani klas równoważności.
[^ ...]
[^0-9]dopasowuje dowolny znak nie będący cyfrą.
|
^P|[0-9]dopasowuje dowolny łańcuch, który pasuje albo do `^P' albo do `[0-9]'. To znaczy, że dopasowuje dowolny łańcuch zaczynający się od `P' lub zawierający cyfrę. Alternatywa odnosi się do największego możliwego wyrażenia regularnego występującego po jednej ze stron. Innymi słowy, `|' ma najniższy priorytet ze wszystkich operatorów wyrażeń regularnych.
(...)
*
ph*stosuje symbol `*' do poprzedzającego go `h' i szuka dopasowań pojedynczego `p', po którym występuje dowolna ilość `h'. Dopasuje ono również samo `p', jeśli nie wystąpią żadne `h'. `*' powtarza najmniejsze możliwe poprzedzające go wyrażenie. (Chcąc powtórzyć większe wyrażenie należy użyć nawiasów.) Odnajduje tyle powtórzeń, ile to możliwe. Na przykład:
awk '/\(c[ad][ad]*r x\)/ { print }' sample
wypisuje każdy rekord z `sample' zawierający łańcuch postaci
`(car x)', `(cdr x)', `(cadr x)', i tak dalej.
Zauważ cytowanie nawiasów przez poprzedzenie ich odwrotnymi ukośnikami.
+
wh+ybędzie dopasowywać `why' i `whhy', ale nie `wy', podczas gdy `wh*y' dopasowywałoby wszystkie te trzy łańcuchy. Prostszym sposobem zapisania ostatniego przykładu `*' jest:
awk '/\(c[ad]+r x\)/ { print }' sample
?
fe?ddopasuje `fed' i `fd', ale nic innego.
{n}
{n,}
{n,m}
wh{3}y
wh{3,5}y
wh{2,}y
awk. Zostały
dodane jako część standardu POSIX, by awk i egrep były ze sobą
zgodne.
Ponieważ jednak stare programy mogą wykorzystywać `{' i `}'
w stałych regexp, domyślnie gawk nie dopasowuje wyrażeń
przedziałowych w wyrażeniach regularnych. Jeżeli podano opcję `--posix'
lub `--re-interval' (zob. 14.1. Opcje wiersza poleceń),
to wyrażenia przedziałowe w wyrażeniach regularnych są dozwolone.
W wyrażeniach regularnych najwyższy priorytet mają operatory `*', `+' id `?', tak samo jak nawiasy klamrowe `{' and `}'. Po nich występuje łączenie, i na koniec `|'. Tak jak w arytmetyce, nawiasy okrągłe mogą zmienić sposób grupowania operatorów.
Jeśli gawk pracuje w trybie zgodności
(zob. 14.1. Opcje wiersza poleceń),
klasy znaków i wyrażenia przedziałowe w wyrażeniach regularnych nie są
dostępne.
W następnej sekcji
omówiono operatory wyrażeń regularnych specyficzne dla GNU i podano
więcej szczegółów dotyczących tego, jak opcje wiersza poleceń wpływają
na sposób, w jaki gawk interpretuje znaki w wyrażeniach regularnych.
gawk
Programy GNU mające działające na wyrażeniach regularnych
udostępniają kilka dodatkowych operatorów tych wyrażeń.
Opisano je w niniejszej sekcji. Są one specyficzne dla
gawk; nie są dostępne w innych implementacjach awk.
Większość dodatkowych operatorów przeznaczonych jest do zadań związanych z dopasowywaniem słów. Do naszych celów, słowo jest ciągiem jednej lub więcej liter, cyfr lub znaków podkreślenia (`_').
\w
[[:alnum:]_].
\W
[^[:alnum:]_].
\<
/\<away/ dopasowuje `away', ale nie `stowaway'.
\>
/stow\>/ dopasowuje `stow', ale nie `stowaway'.
\y
\B
/\Brat\B/ dopasowuje `crate', ale nie
dopasowuje `dirty rat'. `\B' jest w gruncie rzeczy przeciwieństwem
`\y'.
Istnieją jeszcze dwa inne operatory, operujące na buforach. W Emacsie
bufor jest, naturalnie, buforem Emacsa. Przy innych programach,
procedury biblioteczne regexp używane przez gawk traktują jako bufor
cały łańcuch jaki ma zostać dopasowany.
W awk, ponieważ `^' i `$' zawsze działają jako początek
i koniec łańcuchów, wspomniane operatory nie wnoszą żadnych nowych
możliwości. Udostępniane są z uwagi na zgodność z innym oprogramowaniem GNU.
\`
\'
W innych programach GNU operatorem granicy słowa jest `\b'.
Jednak powoduje to konflikt w występującą w języku awk definicji
`\b' jako backspace, więc gawk używa innej litery.
Metodą alternatywną byłby wymóg dwu odwrotnych ukośników w operatorach GNU, ale zostało to uznane za zbyt mylące, a obecna metoda stosowania `\y' dla GNU `\b' wygląda na mniejsze zło.
Rozmaite opcje wiersza poleceń
(zob. 14.1. Opcje wiersza poleceń)
decydują o sposobie, w jaki gawk interpretuje znaki w wyrażeniach
regularnych.
--posix
--traditional
awk.
Operatory GNU nie mają znaczenia specjalnego, nie są dostępne wyrażenia
przedziałowe ani POSIX-owe klasy znaków ([[:alnum:]] i tak dalej).
Znaki opisane ósemkowymi i szesnastkowymi sekwencjami specjalnymi traktowane
są dosłownie, nawet jeśli reprezentują metaznaki wyrażeń regularnych.
--re-interval
Normalnie w wyrażeniach regularnych wielkość liter jest znacząca, zarówno przy dopasowywaniu zwykłych znaków (tj. nie metaznaków), jak i wewnątrz zestawów znaków. Stąd `w' w wyrażeniu regularnych dopasowuje wyłącznie małą literę `w' a nie duże `W'.
Najprostszym sposobem wykonania dopasowania niezależnego od wielkości liter jest użycie listy znaków: `[Ww]'. Może być on jednak niewygodny jeśli trzeba stosować go często; utrudnia też czytanie wyrażeń regularnych. Istnieją dwie alternatywne metody, które mogą się bardziej podobać.
Jednym ze sposobów wykonania dopasowania bez rozróżniania wielkości liter
w danym miejscu programu jest konwersja danych na jednakową wielkość
liter, za pomocą wbudowanych funkcji łańcuchowych tolower lub
toupper (których jeszcze nie omawialiśmy;
zob. 12.3. Funkcje wbudowane działające na łańcuchach).
Na przykład:
tolower($1) ~ /foo/ { ... }
przekształca pierwsze pole na małe litery przed wykonaniem na nim
dopasowania. Działa to w dowolnej implementacji awk zgodnej z POSIX.
Inną metodą, specyficzną dla gawk, jest nadanie zmiennej
IGNORECASE wartości niezerowej (zob. 10. Zmienne wbudowane).
Gdy IGNORECASE jest niezerowe, wszystkie operacje na
wyrażeniach regularnych i łańcuchach ignorują wielkość liter.
Zmiana wartości IGNORECASE steruje dynamicznie wrażliwością programu
na wielkość liter w trakcie jego działania. Domyślnie wielkość znaków jest
istotna, ponieważ IGNORECASE (jak większość zmiennych) jest
inicjowana na zero.
x = "aB" if (x ~ /ab/) ... # ten test się nie powiedzie IGNORECASE = 1 if (x ~ /ab/) ... # a teraz się uda
Ogólnie, nie można wykorzystać IGNORECASE do zrobienia pewnych reguł
niewrażliwymi na wielkość liter a innych wrażliwymi, gdyż nie ma możliwości
ustawienia IGNORECASE tylko dla wzorca konkretnej reguły.
Chcąc zrobić coś takiego, musimy użyć list znaków lub tolower.
Jednak jedną z rzeczy, jakie można zrobić z IGNORECASE, jest
dynamiczne włączanie lub wyłączanie uwzględniania wielkości liter dla
wszystkich reguł naraz.
IGNORECASE można ustawić w wierszu poleceń lub w regule BEGIN
(zob. 14.2. Inne argumenty wiersza poleceń; także
zob. 8.1.5.1. Akcje początkowe i końcowe). Ustawienie
IGNORECASE z wiersza poleceń jest sposobem na uczynienie programu
niewrażliwym na wielkość liter bez konieczności zmieniania go.
Przed wersją 3.0 gawk, wartość IGNORECASE wpływała tylko
na operacje na wyrażeniach regularnych. Nie dotyczyła porównywania
łańcuchów przez `==', `!=', i tak dalej. Począwszy od
wersji 3.0, IGNORECASE ma wpływ zarówno na działania na wyrażeniach
regularnych jak i na łańcuchach.
Począwszy od wersji 3.0 gawk, równoważniki między dużymi a małymi
znakami oparte są na zestawie znaków ISO-8859-1 (ISO Latin-1). Zestaw ten
jest nadzbiorem tradycyjnych 128 znaków ASCII, udostępniającym też wiele
znaków odpowiednich do użytku w językach europejskich [tłum.: niestety --
zachodnioeuropejskich].
Wartość IGNORECASE nie ma znaczenia jeśli gawk pracuje w
trybie zgodności (zob. 14.1. Opcje wiersza poleceń). W trybie
zgodności wielkość liter jest zawsze istotna.
Rozważmy następujący przykład:
echo aaaabcd | awk '{ sub(/a+/, "<A>"); print }'
Przykład ten wykorzystuje funkcję sub (której jeszcze nie omawialiśmy,
zob. 12.3. Funkcje wbudowane działające na łańcuchach)
do zmiany rekordu wejściowego. Występujące tu wyrażenie regularne
/a+/ oznacza "co najmniej jeden znak `a'",
a tekstem zastępującym jest `<A>'.
Wejście zawiera cztery znaki `a'. Jakie będzie wyjście?
Inaczej mówiąc, ile to jest "co najmniej jeden" -- czy awk
dopasuje dwa, trzy czy wszystkie cztery znaki `a'?
Odpowiedź brzmi: wyrażenia regularne awk (i POSIX-a) zawsze
dopasowują pierwszy z lewej najdłuższy ciąg znaków wejściowych,
jaki można dopasować. Zatem, w tym przykładzie, przez `<A>'
zostaną zastąpione wszystkie cztery znaki `a'.
$ echo aaaabcd | awk '{ sub(/a+/, "<A>"); print }'
-| <A>bcd
Przy prostych sprawdzeniach typu pasuje/nie pasuje, nie jest to takie ważne.
Jednak przy
dopasowywaniu tekstów i podstawieniach przez funkcje
match, sub, gsub i gensub, jest bardzo istotne.
Zrozumienie tej zasady jest również istotne przy podziale na pola i rekordy
opartym na wyrażeniach regularnych (zob. 5.1. Jak wejście dzielone jest na rekordy,
a także zob. 5.5. Jak rozdzielać pola).
Prawa strona operatora `~' lub `!~' nie musi być stałym wyrażeniem regularnym (tj. łańcuchem znaków pomiędzy ukośnikami). Może być dowolnym wyrażeniem. Wyrażenie podlega wyliczeniu wartości i jej przekształceniu na łańcuch, jeśli zachodzi taka potrzeba; zawartość łańcucha używana jest jako wyrażenie regularne. Wyrażenie regularne obliczane w ten sposób nazywane jest dynamicznym wyrażeniem regularnym. Na przykład:
BEGIN { identifier_regexp = "[A-Za-z_][A-Za-z_0-9]*" }
$0 ~ identifier_regexp { print }
przypisuje do identifier_regexp wyrażenie regularne
opisujące nazwy zmiennych awk i sprawdza, czy rekord wejściowy
pasuje do tego wyrażenia.
Uwaga! W stosowaniu operatorów `~' i `!~'
istnieje różnica pomiędzy stałym regexp ujętym w ukośniki a stałą
łańcuchową ujętą w cudzysłowy. Jeśli mamy zamiar użyć stałej łańcuchowej,
powinniśmy rozumieć, że łańcuch w gruncie rzeczy badany jest
dwukrotnie: za pierwszym razem gdy awk czyta program, i za
drugim gdy zamierza dopasować łańcuch stojący po lewej stronie operatora ze
wzorcem po prawej. Obowiązuje to nie tylko dla stałych łańcuchowych, ale
i dowolnych wyrażeń o wartości łańcuchowej (jak identifier_regexp
powyżej).
Co wynika z tego, że łańcuch jest sprawdzany dwukrotnie? Istotna różnica występuje przy sekwencjach specjalnych, w szczególności przy odwrotnych ukośnikach. W celu umieszczenia odwrotnego ukośnika w wyrażeniu regularnym wewnątrz łańcucha musimy wpisać dwa odwrotne ukośniki.
Na przykład, /\*/ jest stałą regexp opisującą dosłowne `*'.
Potrzebny jest tylko jeden odwrotny ukośnik. Chcąc zrobić to samo za
pomocą łańcucha, musielibyśmy wpisać "\\*". Pierwszy odwrotny
ukośnik służy tylko do zacytowania drugiego, tak że łańcuch faktycznie
zawiera dwa znaki `\' i `*'.
Skoro do opisu wyrażenia regularnego możemy użyć zarówno stałej typu regexp jak i stałej łańcuchowej, którą z nich powinniśmy zastosować? Odpowiedź brzmi: "stałą regexp", z kilku powodów.
awk potrafi
zauważyć, że podaliśmy wyrażenie regularne i przechowuje je wewnętrznie
w postaci powodującej efektywniejsze dopasowywanie wzorców. Przy zastosowaniu
stałej łańcuchowej, awk musi najpierw przekształcić łańcuch na taką
postać wewnętrzną, a następnie dopiero wykonać dopasowanie wzorca.
Przejdź do pierwszej, poprzedniej, następnej, ostatniej sekcji, spisu treści.