2010-04-20 6 views
6

A 'Perlism' común es la generación de una lista como algo para recorrer en esta forma:¿Puedo usar descomprimir para dividir una cadena en caracteres en Perl?

for($str=~/./g) { print "the next character from \"$str\"=$_\n"; }

En este caso, la expresión regular partido mundial devuelve una lista que es uno de los personajes a su vez de la cadena $str, y asigna ese valor a $_

en lugar de una expresión regular, split pueden usarse de la misma manera o 'a'..'z', map, etc.

estoy en vestigio unpack para generar un campo por interpretación de campo de una cuerda. Siempre he encontrado que unpack es menos directo a la forma en que funciona mi cerebro, y nunca he profundizado tanto en eso.

Como un simple caso, quiero generar una lista de un carácter en cada elemento de una cadena usando descomprimir (sí, sé que puedo hacerlo con split(//,$str) y /./g pero realmente quiero ver si puedo desempaquetar ser usado de esta manera ...)

Obviamente, puedo usar una lista de campos para desempaquetar que es unpack("A1" x length($str), $str) pero ¿hay alguna otra manera en que se parezca a un engomado? es decir, ¿puedo llamar al unpack(some_format,$str) en el contexto de la lista o en un bucle para que unpack devuelva el siguiente grupo de caracteres en el grupo de formatos hasta que se exija $ str?

He leído The Perl 5.12 Pack pod y la Perl 5.12 pack tutorial y the Perkmonks tutorial

Aquí está el código de ejemplo:

#!/usr/bin/perl 
use warnings; 
use strict; 

my $str=join('',('a'..'z', 'A'..'Z')); #the alphabet... 

$str=~s/(.{1,3})/$1 /g;    #...in groups of three 
print "str=$str\n\n"; 

for ($str=~/./g) { 
print "regex: = $_\n"; 
} 

for(split(//,$str)) { 
print "split: \$_=$_\n"; 
} 

for(unpack("A1" x length($str), $str)) { 
print "unpack: \$_=$_\n"; 
} 

Respuesta

9

pack y unpack plantillas se pueden utilizar paréntesis para agrupar las cosas al igual que las expresiones regulares pueden. El grupo puede ser seguido por un conteo repetido. * como un conteo repetido significa "repite hasta que te quedes sin cosas para empacar/desempaquetar".

for(unpack("(A1)*", $str)) { 
    print "unpack: \$_=$_\n"; 
} 

Habría que ejecutar un punto de referencia para averiguar cuál de ellos es el más rápido.

+0

¡Sabía que tenía que ser simple! Ahora que juego con él, '" (A1) * "' glob (mi pregunta) y '" (A1) $ i "' generarán $ i campos. ¡Aterciopelado! ¿Sabes dónde está eso documentado de una buena manera? La mayoría del material en la Web no era excelente ... – dawg

+0

@drewk: en 'perldoc -f pack' (http://perldoc.perl.org/functions/pack.html) en" Suministrar un * para el conteo repetido en lugar de un número, significa usar, sin embargo, cuántos elementos quedan ... "y" Un grupo (A) es una subparálalo entre paréntesis ... " – Ether

+0

@Ether: los ejemplos en perldoc no me hablaron en este caso. La mayoría de los usos de '*' tenían la forma de 'devorar el resto' como en 'unpack' a3/A A '', '007 Bond J'; da ('Bond', 'J') 'y creo que el perldoc en pack/unpack podría ser - más claro ... – dawg

Cuestiones relacionadas