Newsgroup: it.comp.lang.perl
Titolo: problema tr///

Salve,
ho un problema con la funzione tr///.
Dovrei modificare dei nomi dei file nelle ultime 2 cifre che precedono il
primo punto. Ad esempio:
Old Filename: fosP8E4#fosP8E4h01.b1.ab1	
New Filename: fosP8E4#fosP8E4h07.b1.ab1
In particolare le cifre da 01 a 06 devono diventare da 07 a 12.
A tal fine ho scritto :
[..]
substr(@fileNameUpToDot[0], -2, 2) =~
tr/(01)(02)(03)(04)(05)(06)/(07)(08)(09)(10)(11)(12)/;
[...]
che a quanto pare funziona per 01, 02, 03 ma non con le cifre successive,
per cui ottengo:
ESATTI
Old Filename: fosP8E4#fosP8E4h01.b1.ab1	New Filename:
fosP8E4#fosP8E4h07.b1.ab1
Old Filename: fosP8E4#fosP8E4h02.b1.ab1	New Filename:
fosP8E4#fosP8E4h08.b1.ab1
Old Filename: fosP8E4#fosP8E4h03.b1.ab1	New Filename:
fosP8E4#fosP8E4h09.b1.ab1
ERRATI
Old Filename: fosP8E4#fosP8E4h04.b1.ab1	New Filename:
fosP8E4#fosP8E4h00.b1.ab1
Old Filename: fosP8E4#fosP8E4h05.b1.ab1	New Filename:
fosP8E4#fosP8E4h01.b1.ab1
Old Filename: fosP8E4#fosP8E4h06.b1.ab1	New Filename:
fosP8E4#fosP8E4h02.b1.ab1
non risco a darmi spiegazioni del perchč...
Idee ed alternative sono ben accette!
ciao
Stefano
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

Idee ed alternative sono ben accette!
Devi usare l'operatore s///, se vuoi utilizzare le espressioni regolari, o
costruirti una procedura di sostituzione ad hoc.
Ciao.

 [...]
Puoi fare questo:
s/(\d\d)(?=.{7}$)/sprintf "%02d",$1+6/e;
direttamente sulla stringa che contiene l'intero nome.
Questa e' un'idea, ovviamente puoi cambiare la parte nel lookahead in modo
che $1 nel RHS identifichi esattamente le due cifre che vuoi cambiare.

 s/(dd)(?=.{7}$)/sprintf "%02d",$1+6/e;
grazie mille, ma...me lo potresti spiegare?
e poi...in tal caso, 04+6 mi da 10 o 010 ?


 e poi...in tal caso, 04+6 mi da 10 o 010 ?
Non importa, perche' la sprintf produce comunque il risultato giusto,
ossia %02d (2 cifre con eventuale 0 iniziale). Se invece non si usa la
sprintf, il risultato potrebbe non essere quello voluto:
$ echo 'fosP8E4#fosP8E4h01.b1.ab1' | perl -pe 's/(\d\d)(?=.{7}$)/$1+6/e;'
fosP8E4#fosP8E4h7.b1.ab1
Questo non va bene perche' nella valutazione di 01+6 Perl trasforma il tutto
in un numero, e quindi toglie gli zeri non significativi. Con la sprintf si
forza la ri-trasformazione in stringa col formato voluto.
Ciao!

 persi nella risposta).
ok...il problema č che non sempre la regola dei 7 caratteri č rispettata.
Per questo ho usato:
[...]
my @fileNameUpToDot = split (/./, $file);
substr(@fileNameUpToDot[0], -2, 2)
che mi intercetta gli ultimi 2 caratteri prima del primo punto.
come modifico questa variabile cosě ottenuta con i tuoi suggerimenti?
ho usato: substr(@fileNameUpToDot[0], -2, 2) =~ s/$1/sprintf "%02d",$1+6/;
ma ottengo:
	New Filename: fosP8E4#fosP8E4hsprintf "%02d",+606.g1.ab1


 New Filename: fosP8E4#fosP8E4hsprintf "%02d",+606.g1.ab1
Il $1 si usa nella parte destra della sostituzione, non a sinistra, e
inoltre devi usare lo switch /e.
Se la condizione e' "i due caratteri (cifre) che precedono il primo punto
nella stringa", allora usa questo, anche senza lookahead:
...
my $file='fosP8E4#fosP8E4h01.b1.ab1';
$file =~ s/([^.]+)(\d\d)/sprintf "%s%02d",$1,$2+6/e;
print "New Filename: $file\n";
Sostanzialmente, prende la piu' lunga stringa possibile che non contiene
punti, seguita da due cifre. Se il formato e' quello che hai descritto,
dovrebbe proprio prendere le due cifre che ti interessano. 

 come modifico questa variabile così ottenuta con i tuoi suggerimenti?
Puoi anche non usare espressioni regolari:
my @fileNameUpToDot = split (/\./, $file);
substr($fileNameUpToDot[0],-2,2,
sprintf "%02d",substr($fileNameUpToDot[0], -2, 2)+6);
$file=join ".",@fileNameUpToDot;


 print "New Filename: $filen";
perfetto...questa soluzione è quella più vicina a cosa avevo in mente!!
grazie infinite.
S.
