Newsgroup: it.comp.lang.perl
Titolo: Primi passi con Perl

Ciao a tutti,
mi sono da poco "buttato" sul Perl; questo sotto č uno di quegli stupidi esempi
autodidattici che uno masochisticamente si inventa per digerire un argomento,
solo che non funziona.
L' intento sarebbe quello di estrarre dall' array i numeri con 1,2,3,4 e 5
cifre usando le espressioni regolari
#/usr/bin/perl
@numbers=(1,12,243,761,92735,336129,63,2835,835,49654657);
for ($index = 0; $index < 10; $index++)
{
if  ($numbers[$index] = [0-9]{1,5})  { print "$numbers[$index] \n" }
}

 }
Ciao,
io farei una modifica e correggerei quello che mi sembra un errore, per cui:
#!/usr/bin/perl
 @numbers=(1,12,243,761,92735,336129,63,2835,835,49654657);
 
# modifica migliorativa
 foreach $num (@numbers) 
 {
# correzione errore
 if  ($num =~ /[12345]/)  { print "$num\n" }
 }
-- 
-- Marco Allegretti --
http://www.shishii.com

  }
Non mi pare! ;)
Cosě prende le stringhe che hanno ALMENO le cifre 1 o 2 o 3 o 4 o 5.
Se non ho capito male, dovrebbe invece prendere i numeri con un NUMERO
di cifre pari a 1|2|3|4|5
Una (TIMTOWTDI) delle maniere potrebbe essere:
foreach my $number ( @numbers ) {
	print $number."\n" if ($number =~ /^\d{1,5}$/)
}
-- 
$_=q,6;-16;-1;-8;0;7;-13;-12;-9;-3;13#4A75737420616E6F74686572,,($_,$b)=
split?#?;@b=split?;?;map{$c.=$_,$d.=chr$b[$e++]+ord}split??,pack'H24',$b
;chop$d,print$c.chr(32).$d

 }
Ciao,
in effetti penso che avevo capito male io e che hai ragione.


}
Funziona !
Quello che non ho capito è l'uso del simbolo di scalare $ dentro l'espressione
regolare.
A dire la verità avevo già provato una correzione del genere:
                for ($index = 0; $index < 10; $index++)
                {
                if  ($numbers[$index] =~ /[0-9]{1,5}/)  { print
"$numbers[$index] \n" }
                }
ma il risultato era l'elenco completo dell'array, anche se per me l'espressione
"/[0-9]{1,5}/"  significa "qualsiasi numero con un'occorrenza minima di 1 e
massima di 5"; quindi ancora non capisco perchè non funziona...e sia
sufficiente aggiungere "$" perchè tutto si aggiusti.
Ho pure provato l'espressione [12345] suggeritami da shishii, e viene
effettivamente interpretata da Perl così come dici tu, ossia "prende le
stringhe che hanno ALMENO le cifre 1 o 2 o 3 o 4 o 5.": strano che non sia
necessario un separatore tra le cifre, ossia [1,2,3,4,5]; per me (erroneamente,
come ho poi verificato) [12345] avrebbe significato "da 0 a 12345" oppure
"almeno 12345" (questo perchè non sono abituato a un solo scalare dentro le
quadre), ove "12345" si legga "dodicimilatrec....".
                                                    Ciao
                                                            Marco

}
Funziona !
Quello che non ho capito è l'uso del simbolo di scalare $ dentro l'espressione
regolare.
A dire la verità avevo già provato una correzione del genere:
                for ($index = 0; $index < 10; $index++)
                {


 regolare.
dal prompt, fai:
perldoc perlre
per avere info sulle espressioni regolari e nel quale trovi:
 By default, the "^" character is guaranteed to match only the beginning
 of the string, the "$" character only the end


 un'occorrenza minima di 1 e massima di 5"; quindi ancora non capisco
 
Come ti hanno detto, $ identifica la fine della stringa e ^ l'inizio
quindi:
   l'espressione          identifica
  /[0-9]{1,5}/        una stringa che contiene almeno una cifra
  /[0-9]{1-5}$/       una stringa che finisce con almeno una cifra
  /^[0-9]{1,5}/       una stringa che comincia con almeno una cifra
  /^[0-9]{1-5}$/      una stringa composta solo di cifre,
                      almeno una e al più 5
Quindi quello che vuoi tu è l'ultima forma. in effetti
"azerty1hahah" =~ /[0-9]{1,5}/
"azerty1234567890" =~ /[0-9]{1-5}$/ 
"1234567890azerty" =~ /^[0-9]{1,5}/
quindi nessuna delle tre prime regexp identifica ciò che ti serve. Giusto
per puntualizzare, puoi sostituire [0-9] con \d. Quindi:
/^\d{1-5}$/
è ciò che cerchi.
Saluti
-- 
Leo TheHobbit 
IRCnet #roma2
ICQ 56656060
e-mail: remove 
dont.spam.me
 from above address

Credo di avere capito...
Ossia, riciclando il tuo esempio   "azerty1234567890" =~ /[0-9]{1-5}$/
Perl non si ferma alle cinque occorrenze per ciò che "Apache 3000"
(
http://www.apache.3000.it/
 da cui sto studiando - che ne pensi ? -) definisce
"avidità del linguaggio", e quindi occorre definire i limiti con ^ e $.
Grazie
Marco

Problema risolto !
Prossimo impegno: tradurre la tua firma (sempre che non mi scombini il sistema)
                                            Grazie
                                                        Marco

Marco scripsit:

No, qui nn è questione dell'avidità. E' proprio la semantica delle
espressioni regolari. Un'espressione regolare definisce un insieme di
stringhe. /[0-9]{1-5}$/ definisce l'insieme delle stringhe che "finiscono
con 1, 2, 3, 4 o 5 cifre". Ovviamente, questo
insieme può anche essere definito come "le stringhe che finiscono con una
cifra". Cioè, /[0-9]$/ e /[0-9]{1-5}$/ definiscono lo stesso insieme di
stringhe. Si potrebbe dimostrarlo, ma un esempio può aiutarti meglio.
"a1" =~ /[0-9]$/ (ovvio)
"a1" =~ /[0-9]{1-5}$/ (infatti, la stringa termina con 1 cifra, quindi..)
Ciao


>
che mi ha fatto pensare che {2,6} significasse non "min 2, max 6", ma "almeno
due, tre... o sei" e quindi anche 9 o 197369 cifre.
                                                                        Ciao
Marco

 "almeno due, tre... o sei" e quindi anche 9 o 197369 cifre.
Esatto, però il problema è un altro. Se perl cerca di verificare la
stringa "abc123x" contro l'espressione regolare /[0-9]{2,6}/ procede (più
o meno) così:
1. il primo carattere di "abc123x" è 'a', che non soddisfqa [0-9],
2. il secondo carattere di "abc123x" è b, che non soddisfa [0-9]
3. il terzo carattere di "abc123x" è 'c', che non soddisfa [0-9]
4. il quarto carattere di "abc123x" è 1, che soddisfa [0-9]. 
5. il sesto carattere di "abc123x" è 2, che soddisfa [0-9].
A questo punto, l'espressione regolare /[0-9]{2,6}/ è soddisfatta, ma
scatta l'avidità:
6. il settimo carattere di "abc123x" è 3, che soddisfa [0-9], quindi 123
   soddisfa /[0-9]{2,6}/
7. l'ottavo carattere di "abc123x" è 'z', che non soddisfa [0-9], quindi 
   la sottostringa 123x non soddisfa /[0-9]{2,6}/. Si torna indietro al
   punto 6.
Puoi vedere meglio questo, con il seguente programmino
#!/usr/bin/perl
use re "debug";
"abc123x" =~ /[0-9]{2,3}/;
oppure mettendo delle parentesi attorno a [0-9]{2,3} e facendo stampare
$1.
Comunque, leggi il capitolo 5 del 'Camel book'....


 non-cifra.
Per l'insieme delle cifre non si fa prima ad usare \d e per quello 
delle non-cifre \D ?
-- 
Saluti,
Giancarlo

 Ma lui vuole 0-9, mentre AFAIR \d comprende anche [\.\,\+\-]
Camel book says:
Code    Matches
...     ......
\d      A digit, same as [0-9)
-- 
Saluti,
Giancarlo

Ci sono!
A questo punto, dopo aver fatto un puzzle con i consigli di tutti, credo di
avere digerito l'argomento avidità e allo stesso tempo di avere delineato tutti
i possibili aspetti del problema; l'ultimo pezzo del puzzle l'ho trovato nella
dritta di Marco Balestra:
/[^0-9][0-9]{1,5}$/
Questo vale nel caso in cui le cifre numeriche siano precedute da una
non-cifra.
Perciò, riassumendo:
1. /^\d{1-5}$/                  nel caso di sole cifre
2. /[^0-9][0-9]{1,5}$/          per scalari del tipo aaa12345
3. /[^0-9][0-9]{1,5}[^0-9]$/    per scalari del tipo aaa12345aaa
4. /^[0-9]{1,5}[^0-9]$/         per    "     "    "  12345aaa
Giusto ?
Poi, per il resto, credo proprio che appena posso mi comprerò il
plurimenzionato 'Camel book' che, se ho capito bene, dovrebbe essere
'Programmare in Perl' di Larry Wall & C ed. Jackson Libri, e non 'Perl guida di
riferimento' di Ellen Siever ed. Apogeo...
Anche perchè, provando il tuo "programmino":
  #!/usr/bin/perl
use re "debug";
"abc123x" =~ /[0-9]{2,3}/;
il risultato ottenuto è:
[root@localhost Prove]# perl prova2
Compiling REx `[0-9]{2,3}'
size 12 first at 3
1: CURLY {2,3}(12)
3: ANYOF[0-9](0)
12: END(0)
stclass `ANYOF[0-9]' minlen 2
Matching REx `[0-9]{2,3}' against `abc123x'
Setting an EVAL scope, savestack=3
3 <abc> <123x> | 1: CURLY {2,3}
ANYOF[0-9] can match 3 times out of 3...
Setting an EVAL scope, savestack=3
6 <abc123> <x> | 12: END
Match successful!
Freeing REx: `[0-9]{2,3}'
[root@localhost Prove]#
Cioè....Boh!
Comunque, quel che è certo è che tu e tutti quelli che mi hanno aiutato siete
soci onorari del club della birra, che riunisce tutti coloro cui ne devo
una...dovrò aprire un pub.
Ciao
Marco

Ci sono!
A questo punto, dopo aver fatto un puzzle con i consigli di tutti, credo di
avere digerito l'argomento avidità e allo stesso tempo di avere delineato tutti
i possibili aspetti del problema; l'ultimo pezzo del puzzle l'ho trovato nella
dritta di Marco Balestra:
/[^0-9][0-9]{1,5}$/
Questo vale nel caso in cui le cifre numeriche siano precedute da una
non-cifra.
Perciò, riassumendo:


 4. ^[0-9]{1,5}[^0-9]$         per    "     "    "  12345aaa
Solo una nota generale: come usi nella prima \d per [0-9] lo puoi usare 
in tutte le altre e in piu' puoi usare \D per [^0-9], a mio avviso 
rendi le regex molto piu' leggibili.
-- 
Saluti,
Giancarlo