Newsgroup: it.comp.lang.perl
Titolo: spezzettare

ciao
come faccio a spezzettare a 3 a 3 la seguente stringa
"gttttaaatcaatct"
in modo da ottenere
"gtt",
"tta",
"aat",
"caa",
"tct"
?
Grazie
 Raffaello
P.S.: Ho provato con split(/.{3}/,$variabile) ma non va. :(
      Mi sa che devo mettere i singoli elementi in un array
      ottenuto da split(//,$variabile) e poi andare in ciclo.

 
 @chunks =  split /(.{3})/, $string;
Nota le parentesi tonde. Oppure:
 
    sub break_string
    {
	my $len = $_[1] || 1;
	my @result;
	my $pos = 0;
	while( $pos < length( $_[0] ) )
	{	
		push @result, substr($_[0], $pos, $len );
		$pos += $len;
	}
	return @result;
     }
   @chunks = break_string( $string, 3 );
Max

Raffaello Galli wrote:

In generale con stringhe di lunghezza arbitraria (non necessariamente 
multipla di 3) potresti fare cosi':
.....
while ($stringa =~ /(.{1,3})/g )
  {
    $res->{$i++} = $1;
  }
.....
Ottieni un hash con chiavi del tipo 1 2 3 4  etc etc, che contengono tutte 
sottostringhe di lunghezza pari a 3, tranne l'ultima in alcuni casi, a 
seconda se la stringa originaria ha lunghezza multipla di 3 o meno.
Se hai bisogno che le sottostringhe siano memorizzate in un array basta 
cambiare l'istruzione del ciclo nella seguente:
push @res, $1;

Nota le parentesi tonde. Oppure:
Da perldoc -f perlfunc:
  << Anything matching PATTERN is taken to be a delimiter 
  separating the fields. ( Note that the delimiter may be 
  longer than one character. ) >>
  Quindi quello che viene specificato nella regexp che si
passa a split e` il _delimitatore_ usato per lo split.
Inoltre:
  << If the PATTERN contains parentheses, additional list 
  elements are created from each matching substring in the 
  delimiter. >>
  In altre parole, alla lista ritornata da split vengono 
aggiunti elementi per ognuna delle sottostringhe di $string 
che matchano la sottostringa di PATTERN messa tra parentesi
(in questo caso, tutto il PATTERN).
Nella documentazione di split ci sono un paio di esempi 
chiarificatori, che riporto di seguito (sono brevi):
    split(/([,-])/, "1-10,20", 3);
Ritorna la lista (1, '-', 10, ',', 20).
    $header =~ s/\n\s+/ /g;  # fix continuation lines
    %hdrs   =  (UNIX_FROM => split /^(\S*?):\s*/m, $header);  
E` da provare su un header preso a casaccio (notare che in 
questo caso *non tutto* il delimitatore viene catturato).
Quindi, e chiudo, l'esempio di Max, se applicato alla stringa 
"gttttaaatcaatct" ritorna una lista formata dai delimitatori
(.{3}) _E_ dagli elementi delimitati da questi ultimi, vale a
dire tanti ''. 
Fine. Mi ero chiesto come funzionasse l'esempio di Max e mi
pareva interessante condividere.
ciao
Stefano

 pareva interessante condividere.
Beh, il mio esempio non funziona proprio. (Non come voleva l'OP, almeno.)  
Volevo vedere se eravate attenti. :-)
Cosě č meglio:
  my @chunks = ( $string =~ /(.{3}/g );
Max

  my @chunks = ( $string =~ /(.{3}/g );
Ne convengo :)
ciao

Max M. wrote:

Nel seguente modo si estrae anke l'ultima sottostringa, nel caso in cui la 
stringa originaria non abbia lunghezza multipla di 3. :)
my @chunks = ( $string =~ /(.{1,3})/g );
Ciao.



In effetti nel problema che dovevo risolvere la lunghezza della stringa
non e' sempre multipla di 3.
Grazie a tutti per l'aiuto
 ciao
Raffaello

push @res, $1;
Vabbe', "Famolo strano!":
  @res = unpack("a3" x (length($stringa)/3), $stringa);
Se si vuole anche l'ultimo pezzetto, nel caso la lunghezza della stringa non
sia multipla di 3:
  my $resto = length($stringa) % 3;
  push @res, substr($string, -$resto) if $resto;
Ciao.


Ciao


Dal punto di vista dell'efficienza, credo che la cosa migliore sia un ciclo
con substr. unpack in realta` e` molto efficiente, ma c'e` di mezzo la
divisione e il modulo. Le espressioni regolari con quantificatori sono
probabilmente la cosa meno efficiente, ma probabilmente se la caverebbero
bene perche' non richiedono altre operazioni al contorno.
In realta`, bisognerebbe verificare le prestazioni di ogni soluzione. In
pratica, dubito che ne valga la pena.
Ciao.

 "gttttaaatcaatct"
Bioinformatico? =)
-- 
Paolo "Razor" Greco
IPL MUD - 
http://razor.tera.it/
($work,$life) = split /$/, $time unless $money > 10000000;

 Bioinformatico? =)
Mi sembra evidente ... ;)
 Raffaello

 Bioinformatico? =)
Se per "spezzettare" intendi definire un array in cui ogni elemento contenga
3 lettere fai cosě:
$str = 'gttttaaatcaatct';
@ary = split /(...)/, $str;
print "@ary"; # per vedere l'effetto che fa :-)
ciao
dd
PS Ma la faccenda del DNA non č composta da 4 elementi? Perché la vuoi
spezzettare a gruppi di 3?