Newsgroup: it.comp.lang.perl
Titolo: Com'e' bello con le regexp... :)

Salve a tutti,
ho appena finito di leggere la "perlrequick" e devo dire che le regexp
sono davvero appassionanti... :)
Cosi' ho deciso di provare ad usarne una su un file di testo...
Il file si presenta con righe del genere:
"[nome1] [nome2] --- 150Kb\n"
Che vorrei trasformare semplicemente in:
"[nome1] [nome2]\n\t\tLen: 150Kb\n\n"
Quindi eliminare i '-', andare a capo, centrare un po' e lasciare una
riga vuota. Molto banale, se non fosse per il fatto che di '-' in quella
posizione ce ne possono essere in numero variabile a partire da 0 e che
in [nome2] e' possibile trovarne (ma in [nome2] non ci sono spazi).
Ecco la regexp che sono riuscito a 'forgiare' :) :
	s" *-* (\d.*$)"\n\t\tLen: $1\n"g;
Effettivamente funziona; l'unico problema e' che se [nome2] inizia con
una cifra, 'matcha' a partire da li'...
Questo sarebbe un possibile work-around...
	s"^(\w+ \w+) *-* (\d.*$)"$1\n\t\tLen: $2\n"g;
ma non mi piace e, sopratutto, non funziona, per motivi che adesso mi
sfuggono (ho sonno... :) )
Non c'e' che dire... ho scelto l'esempio giusto per iniziare... :)
Non so se qualcuno avra' la voglia di leggere e comprendere le regexp
che ho postato quassu'... e' questa la cosa brutta del perl...
Se non avete voglia, fa nulla... non mi serve per lavoro questo
programma... non ho limiti di tempo per arrivare ad una soluzione :)
Solo un paio di domande:
Al posto di "\t\t" nella stringa che dovrebbe sostituire, come posso
scrivere per abbreviare ? una specie di ["\t" x 2]... ma non funziona...
forse perche' e' seguito da altri caratteri... mah...
Come si cancella un file dall'hd ? Sono sotto win2kpro, ho i privilegi
di root e sono su ntfs. Unlink non funziona, se faccio 
	system("del", $file);	oppure:		system("del " . $file);
non funziona lo stesso in quanto il descrittore del file e' qualcosa
come "GLOB(hex num.)"... Come ricavo il nome del file a partire dal
descrittore ?
E' possibile trovare il 'Camel Book' on-line ?
Perche' hanno inventato il perl quando gia' c'era il C/C++ e la shell ?
Perche' non si crea uno strato piu' 'astratto' per lavorare coi socket ?
Perche' viviamo ? Da dove veniamo ? Dove andiamo ? Perche' mi state
mandando a f... ? :))
Lasciate perdere l'ultimo group di domande... ;)
Thanks in adv.,
micheal
-- 
nothing's real

 
Parto dal presupposto, che mi sembra ovvio, che né nome1 né nome2
contengono delle parentesi quadre. In questo caso è un ottima idea quella
di usare le espressioni regolari 'non greedy':
/^(\[.*?\])\s+(\[.*?\])\s*-*\s*(\S.*)$/;
print "$1 $2\n\tLen: $3\n";
Spiegazione: la differenza tra .* e .*? è che la prima prova a matchatre
_tutti_ i carateri a disposizione, poi se non ne restano abbastanza per
matchare il resto della re, 'lascia andare' un carattere alla volta.
Invece, *.? prova prima a matchare 0 caratteri, se riesce a matchare il
resto della RE è contenta, senno riprova matchando 1 carattere, poi 2,
3... In altre parole, /\[.*?\]/ è, dal punto di vista dei risultati,
equivalente a /\[[^\]]*\]/, cioè matcha una stringa che comincia con [,
ed è costituita da tutti i caratteri fino alla prima ].
Usando queste due istruzioni, puoi fare tutto con un 'one liner':
perl -ne 'next unless /^(\[.*?\])\s+(\[.*?\])\s*-*\s*(\S.*)$/;print "$1 $2\n\tLen:$3\n";'file1...>risultato
dove file1... è (sono) il (i) file contenenti i dati e risultato è il
file da costruire. 
Carino, no? :))))
-- 
Leo TheHobbit 
IRCnet #roma2
ICQ 56656060
e-mail: remove 
dont.spam.me
 from above address