Znaki * oraz + to tak zwane kwantyfikatory, oznaczają ilość wystąpień. Dla przypomnienia C* oznacza dowolną ilość znaków C, również 0 znaków C, zaś C+ to 1 lub więcej wystąpień C. Dla przypomnienia + to kwantyfikator wprowadzony w ERE, zaś * to "uniwersalny" kwantyfikator, występuję zarówno w BRE jak i ERE.
Bywa, że wyszukiwanie za pomocą kwantyfikatorów nie działa tak, jak tego oczekuje programista. Przykład:
<autor1> poszedł o krok dalej od malarza do projektanta obrazów. U szczytu swojej sławy jako malarz, <autor2> miał wielu asystentów
Zdanie z biografii Andy Warhola. Biografia jest zapisana w pliku plik.txt, zadaniem jest zamiana <autor1> oraz <autor2> na Andy Warhol. Pozornie wydaje się to proste, wystarczy wykonać polecenie:
- sed -n -e 's/<.*>/Andy Warchol/gp' plik.txt
jednak po wykonaniu tego polecenia otrzymamy:
Andy Warhol miał wielu asystentów
a nie o to chodziło, przecież! Dzieje się tak ponieważ kwantyfikator * jest zachłanny. Stara się znaleźć jak najdłuższe dopasowanie. W tym przypadku jest to dopasowanie od pierwszego znaku < do ostatniego znaku >. Aby poprawie wykonać zadanie wystarczy nieco zmodyfikować polecenie:
- sed -n -e 's/<[^>]*>/Andy Warchol/gp' plik.txt
[^<]* oznacza dowolną ilość wystąpień każdego znaku z wyłączeniem znaku <.
UWAGA: Standardowe kwantyfikatory POSIX (* oraz +) są zachłanne.
NON-GREEDY QUANTIFICATION
Powyższe problemy spowodowały wprowadzenie tzn. niezachłannych kwantyfikatorów (non-greedy quantyfication). Niezachłanne (non-greedy) kwantyfikatory są oznaczone bardzo podobnie do ich zachłannych (greedy) odpowiedników. Różnica polega znajdowaniu najmniejszego (inaczej niż w zachłannych kwantyfikatorach) dopasowania.
| C*? |
dowolna ilość znaków C, również 0 znaków C |
| C+? |
1 lub więcej wystąpień C |
| C\{n,\}? |
nie mniej niż n wystąpień znaku C |
| C\{,m\}? |
nie więcej niż n wystąpień znaku C |
| C\{n,m\}? |
nie mniej niż n i nie więcej niż m wystąpień znaku C |
sed nie wspiera niezachłannych kwantyfikatorów. Aby pokazać ich działanie skorzystamy z perl. Najpierw sprawdźmy jak działa w perl zachłanna *. Po wykonaniu polecenia:
- perl -p -e 's/<.*>/Andy Warchol/gp' plik.txt
otrzymamy wynik analogiczny do pierwszego z powyższych wywołań sed.
Natomiast gdy zmodyfikujemy * poprzez ?, czyli uczynimy * niezachłanną, to w efekcie wywołania
- perl -n -e 's/<.*?>/Andy Warchol/gp' plik.txt
otrzymujemy:
Andy Warchol poszedł o krok dalej od malarza do projektanta obrazów. U szczytu swojej sławy jako malarz, Andy Warchol miał wielu asystentów
czyli to, co było celem od początku.