2014-11-06 15 views
6

Sono profondamente perplesso dal modo in cui grep sembra analizzare una regex:Grep e regex: perché sto evadendo le parentesi graffe?

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

che non può essere giusto. Perché sto sfuggendo alle parentesi graffe che fanno parte di un componente "abbina il precedente, N volte" (e non, per esempio, le parentesi quadre)?

L'escaping non dovrebbe essere necessario solo quando sto scrivendo un'espressione regolare che corrisponde effettivamente a { e } come caratteri letterali nella stringa di query?

Più di un cri de coeur di qualsiasi altra cosa, ma sono curioso di sapere la risposta.

+0

consigliamo di dare un'occhiata a: http://www.grymoire.com/Unix/Grep.html e http://www.grymoire.com/Unix/ Regular.html – HuStmpHrrr

risposta

6

Questo perché {} sono caratteri speciali e devono essere gestiti diversamente per avere questo comportamento speciale. In caso contrario, saranno trattati come letterali { e }.

è possibile scappare come hai fatto:

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

o utilizzare grep -E:

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

senza alcuna elaborazione:

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

Da man grep:

-E, --extended-regexp

Interpreta modello come espressione regolare estesa (ERE, vedi sotto). (-E è specificato da POSIX.)

...

espressioni regolari

Un'espressione regolare è un modello che descrive un insieme di stringhe. Le espressioni regolari sono costruite in modo analogo alle espressioni aritmetiche , utilizzando vari operatori per combinare le espressioni più piccole .

grep capisce tre versioni differenti di espressioni regolari sintassi:. “Base”, “esteso” e “perl” In GNU grep, non v'è alcuna differenza di funzionalità disponibili tra base ed estese sintassi. In altre implementazioni, le espressioni regolari di base sono meno potenti. La seguente descrizione si applica alle espressioni regolari estese ; le differenze per le espressioni regolari di base sono riassunte in seguito . Le espressioni regolari Perl forniscono funzionalità aggiuntive, e sono documentate in pcresyntax (3) e pcrepattern (3), ma potrebbero non essere disponibili su tutti i sistemi.

...?

base vs espressioni regolari estese

Nelle espressioni regolari base i meta-caratteri, +, {, |, (e) perdono il loro significato speciale; utilizzare invece le versioni backslash \?, \+, \{, \|, \( e \).

+1

Mi avrebbe risparmiato un sacco di battute per includere la spiegazione dal manuale piuttosto che rotolare la mia! –

+0

Ho ricevuto un downvote, non sono sicuro del perché. Se è a causa della mancanza di spiegazioni, stavo aggiornando :) – fedorqui

+0

@Tom Fenech Preferisco fare riferimento alla pagina 'man', non sono bravo a scrivere un buon inglese ad alta velocità :) – fedorqui

5

La risposta si riferisce alla differenza tra Basic Regular Expressions (BRE) e Extended (ERE).

  • In modalità BRE (vale a dire quando si chiama grep con alcun argomento per specificare in altro modo), il { e } vengono interpretati come caratteri letterali. Sfuggirli con \ significa che devono essere interpretati come un numero di istanze del modello precedente.

  • Se si sceglie di usare grep -E invece (modalità ERE), si sarebbe in grado di utilizzare { e } senza sfuggire per fare riferimento al conteggio. In modalità ERE, l'escaping delle parentesi le fa invece interpretare alla lettera.

0

Invece fanno

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