PDA

Visualizza la versione completa : Chiarimento su RE stile Unix


zenzero
19-12-2007, 12:21
Ciao,
ho un file con all'interno le seguenti tre linee:

0123456789
dante12345
12345dante

ora eseguo:

cat nome_file | grep -E [^0-9]

il risultato è:
dante12345
12345dante

Quello che non capisco è perche le due linee sopra non vengo eliminate. L'insieme dei caratteri 0-9, non dovrebbe essere preso in considerazione. Sicuramente mi sfugge qualcosa di concettuale ma non riesco a capire...

grazie
ciao

PinguinoGoloso
19-12-2007, 12:30
Perchè il comportamento delle RE in unix di default è "greedy" (avido), cioè si estendono al massimo possibile finchè non interviene una clausola che le limita.
Devi includere nella RE una regola che escluda i caratteri alfabetici.

zenzero
19-12-2007, 12:32
Grazie,
ma non è tanto chiaro potresti farmi un esempio banale o spiegarmelo in parole più povere?

grazie tante ancora.

PinguinoGoloso
19-12-2007, 12:39
Toh: http://en.wikipedia.org/wiki/Regular_expression .

cacao74
19-12-2007, 13:05
L'espressione regolare "[^0-9]" descrive del testo che NON comprende i caratteri numerici.
Pertanto i risultati che hai ottenuto (contengono il testo "dante") sono corretti.


Per ottenere quanto supponevi, puoi fare il matching inverso usando l'opzione "-v"


cat nome_file | grep -v "[0-9]"


ciao

zenzero
19-12-2007, 13:52
I risultati che ho ottenuto però, non contengono solo del testo ma, anche i caratteri numerici che non dovrebbero matchare con il pattern della regular expression. Credo la spiegazione giusta sia quella di PinguinoGoloso ma non riesco ancora a metterla a fuoco.

ciao

cacao74
19-12-2007, 21:28
Originariamente inviato da zenzero
I risultati che ho ottenuto però, non contengono solo del testo ma, anche i caratteri numerici che non dovrebbero matchare con il pattern della regular expression. Credo la spiegazione giusta sia quella di PinguinoGoloso ma non riesco ancora a metterla a fuoco.

ciao
Allora... secondo me...
la descrizione che ha indicato PinguinoGoloso non e' propriamente corretta.
Le RE sono si avide (basta testare qualche RE con ".*" per rendersene conto. ma nel caso in oggetto,
di avidita' ne ho vista ben poca.
Nel linguaggio reg-exp, la scrittura "[^0-9]" indica un qualunque carattere NON numerico.
Ricercare una riga di testo (grep) in un file, tale per cui la condizione di cui sopra sia soddisfatta, porta ad ottenere i risultati precedenti.


[cacao74@tweety ~]$ cat cacao.txt
0123456789
dante12345
12345dante

[cacao74@tweety ~]$ cat cacao.txt | grep -E "[^0-9]"
dante12345
12345dante

Altro esempio spero chiarificatore:


[cacao74@tweety ~]$ echo "12a34" | grep -E "[^0-9]"
12a34
[cacao74@tweety ~]$ echo "1234" | grep -E "[^0-9]"
...nessun risultato...
[cacao74@tweety ~]$ echo $?
1

Volendo "esagerare" con la ricerca del testo che hai riportato: :-)


[cacao74@tweety ~]$ cat cacao.txt | grep -E "[^0-9]{1,5}"
dante12345
12345dante

[cacao74@tweety ~]$ cat cacao.txt | grep -E "[^0-9]{6}"
[cacao74@tweety ~]$ echo $?
1

[cacao74@tweety ~]$ cat cacao.txt | grep -E "^[0-9]*$"
0123456789

Se cio' non bastasse:


[cacao74@tweety ~]$ cat cacao.txt | grep -oE "[0-9]+"
0123456789
12345
12345

[cacao74@tweety ~]$ cat cacao.txt | grep -oE "[^0-9]+"
dante
dante

:)

Nel link che ti ha fornito PinguinoGoloso trovi sufficienti dettagli per schiarire eventuali dubbi.

Dimenticavo... nella pagina di manuale di "grep" viene chiaramente specificato:


A bracket expression is a list of characters enclosed by [ and ]. It
matches any single character in that list; if the first character of
the list is the caret ^ then it matches any character not in the list.

ciao

zenzero
20-12-2007, 12:05
Ragazzi la soluzione è molto semplice, l'ho saputa parlando con un guru dell'informatica:
nella negazione non esiste il concetto di range... quindi io ho detto fammi vedere tutte le linee che non comprendono i seguenti caratteri: "0" "-" "9" :) :) :)

ciao a tutti e cmq grazie.

weseven
20-12-2007, 12:39
non credo sia quella la soluzione, io sto con cacao74.
altrimenti, con quella spiegazione, echo "1234" | grep -E "[^0-9]" dovrebbe restituire 1234 , cosa che non accade.

cacao74
20-12-2007, 12:43
Originariamente inviato da zenzero
...la soluzione è molto semplice, l'ho saputa parlando con un guru dell'informatica...

...chissa' che discussioni escono fuori...
:incupito:

Loading