2009-01-09 17 views
9

Cuando digo simple, quiero decir, dentro de una expresión, para que pueda incluirlo como un valor en un hash sin prepararlo primero. Publicaré mi solución pero estoy buscando una mejor que me recuerde menos a VB. :)¿Cuál es la forma más sencilla de devolver la primera línea de una cadena multilínea en Perl?

+0

¿Por qué la aversión a prepararlo antes de tiempo? Por lo general, se necesita un mojo elegante para funcionar como un trazador de líneas, que es lo contrario de lo simple. Si bien es divertido resolver estas cosas, rara vez es una buena idea usarlos en un programa real, ya que cuanto más fanático se pone, más difícil es descubrirlo más adelante. –

+0

Es una solución temporal. :) Buen punto sin embargo. – Kev

Respuesta

23

¿Qué tal

(split /\n/, $s)[0] 

?

No tiene que preocuparse por \ n no ser multiplataforma porque Perl is clever enough to take care of that.

+0

¡Gracias, eso es lo que estaba buscando! Espero leer ese artículo también, ya que he tenido problemas con los saltos de línea en el pasado, pero tal vez no fue culpa de Perl. – Kev

+0

Bueno, Perl hace \ n significa cosas diferentes en diferentes sistemas, pero eso no significa que \ n es el separador de registros para la entrada. :) –

+0

Y, esperemos que esta cadena no sea enorme :) –

0
substr($s, 0, index($s, $/) > -1 ? index($s, $/) ||()) 
+0

LOL, oops ... ¡gracias! – Kev

4

Esto no es tan simple como te gusta, pero ser simple solo para ser bajo no siempre debe ser el objetivo.

Puede abrir un gestor de archivo en una cadena (como referencia escalar) y tratarlo como un archivo para leer la primera línea:

 
my $string = "Fred\nWilma\Betty\n"; 
open my($fh), "<", \$string or die ...; # reading from the data in $string 
my $first_line = <$fh>; # gives "Fred" 
close $fh; 

Si realmente quería, supongo que se podría reducir esto a una expresión:

$hash{$key} = do { open my($fh), "<", \$string; scalar <$fh> }; 

No importa el método que elija, siempre se puede hacer una subrutina para devolver la primera línea y luego utilizar la llamada de subrutina en su asignación de hash.

 
sub gimme_first_line { ... } 

$hash{$key } = gimme_first_line(\$string); 
+0

Excepto que esta cadena de varias líneas no se almacena en un archivo ... – Kev

+0

No, es una cadena en la memoria. Aunque puedes tratarlo como un archivo. –

+0

Vaya, no leí su código con mucho cuidado. Huh, ¡no sabía que pudieras hacer eso! – Kev

2
($str =~ /\A(.*?)$/ms)[0]; 

Para las grandes cadenas, esto va a ser más rápido que

(split /\n/, $str)[0] 

según lo sugerido por Manni. [Editar: mención errónea eliminado de split /\n/, $str, 1.]

Si desea incluir el terminal de \n si está presente, agregue \n? justo antes de los paréntesis de cierre en la expresión regular.

+0

En lugar de su primera sugerencia, ¿por qué no simplemente '($ str = ~ /^(.*)/)[0]; ¿? –

+0

@JoshuaGreen: Incluso puede deshacerse del '^' en su solución. De cualquier forma es más conciso que el mío, pero es más difícil de entender porque se basa en que el lector del código es consciente de que '.' no concuerda con' \ n' en ausencia de '/ s'. Para 5 caracteres más, mi código hace que la semántica sea difícil de entender mal. –

+0

Sí, me di cuenta esta mañana que el '^' es superfluo. Honestamente, no pude seguir mucho de lo que estaba haciendo tuyo sin buscarlo todo, pero eso se debió principalmente a la falta de conocimiento de mi parte. Ni siquiera hubiera pensado en usar una expresión regular para esta tarea. –

Cuestiones relacionadas