2014-11-06 10 views
6

Jestem głęboko zaskoczony przez sposób grep wydaje się analizować regex:Grep i regex - dlaczego unikam nawiasów klamrowych?

$ echo "@NS500287" | grep '^@NS500[0-9]{3}' 
#nothing 
$ echo "@NS500287" | grep '^@NS500[0-9]\{3\}' 
@NS500287 

To nie może być prawda. Dlaczego unikam nawiasów klamrowych, które są częścią komponentu "dopasuj poprzedni, N razy" (a nie, powiedzmy, nawiasy kwadratowe)?

Czy unikanie znaków nie jest konieczne tylko wtedy, gdy piszę wyrażenie regularne, które faktycznie pasuje do { i } jako literalne znaki w ciągu zapytania?

Więcej niż cri de coeur niż cokolwiek innego, ale jestem ciekawa odpowiedzi.

+0

polecam rzucić okiem na: http://www.grymoire.com/Unix/Grep.html i http://www.grymoire.com/Unix/ Regular.html – HuStmpHrrr

Odpowiedz

6

To dlatego, że {} są znakami specjalnymi i muszą być traktowane inaczej, aby mieć to specjalne zachowanie. W przeciwnym razie będą one traktowane jako literalne { i }.

Można też uciec jak ty:

$ echo "@NS500287" | grep '^@NS500[0-9]\{3\}' 
@NS500287 

lub użyj grep -E:

$ echo "@NS500287" | grep -E '^@NS500[0-9]{3}' 
@NS500287 

Bez obróbki:

$ echo "he{llo" | grep "{" 
he{llo 

Od man grep:

-E, --extended-regexp

Interpretuje wzorzec jako rozszerzone wyrażenie regularne (ERE, patrz poniżej). (-E jest określony przez POSIX.)

...

WYRAŻENIA REGULARNE

Wyrażenie regularne to wzorzec opisujący zbiór łańcuchów. Wyrażenia regularne są budowane analogicznie do wyrażeń arytmetycznych , za pomocą różnych operatorów łączących mniejsze wyrażenia .

grep rozumie trzy różne wersje składni wyrażeń regularnych . „Basic”, „rozszerzony” i „Perl” W GNU grep, nie ma żadnej różnicy w dostępnych funkcjonalności pomiędzy podstawowych i rozszerzonych składni. W innych implementacjach podstawowe wyrażenia regularne są mniej wydajne. Poniższy opis dotyczy rozszerzonych regularnych wyrażeń ; różnice dla podstawowych wyrażeń regularnych są następnie podsumowywane . Perlowe wyrażenia regularne dają dodatkową funkcjonalność, i są udokumentowane w pcresyntax (3) i pcrepattern (3), ale mogą nie być dostępne w każdym systemie pod numerem .

...?

Podstawowe vs rozszerzonych wyrażeń regularnych

W podstawowych wyrażeń regularnych meta-znaków, +, {, |, (i) tracą swoje szczególne znaczenie; zamiast tego należy użyć odwróconych wersji: \?, , 616713321, ,87.

+1

Zaoszczędziłoby mi wielu naciśnięć klawiszy w celu dołączenia objaśnień do instrukcji, a nie do samodzielnego uruchamiania! –

+0

Otrzymałem głos, nie jestem pewien dlaczego. Jeśli wynika to z braku wyjaśnień, to ja aktualizowałem :) – fedorqui

+0

@Tom Fenech Wolę odnoszenie się do strony "man", nie jestem dobry w pisaniu dobrego angielskiego z dużą prędkością :) – fedorqui

5

Odpowiedź dotyczy różnicy między Basic Expressions (BRE) i Extended (ERE).

  • W trybie BRE (czyli po wywołaniu grep bez argumentu, aby określić inaczej), { i } są interpretowane jako znaki dosłowne. Ucieczka z nich za pomocą \ oznacza, że ​​należy je interpretować jako liczbę wystąpień poprzedniego wzorca.

  • Jeśli było użyć grep -E zamiast (tryb ERE), byłbyś w stanie wykorzystać { i } bez ucieczki odnieść się do hrabiego. W trybie ERE, ucieczka z nawiasów powoduje ich interpretację dosłownie.

0

Zamiast zrobić

echo '@NS500287' | egrep '^@NS500[0-9]{3}' 
#    ^
#    /
#  notice ---