2010-08-26 52 views
8

tengo¿Cómo extraer un número de una cadena en Perl?

print $str; 
abcd*%1234$sdfsd..#d 

La cadena siempre tendría sólo un tramo continuo de números, como 1234 en este caso. El resto será alfabetos u otros caracteres especiales.

¿Cómo puedo extraer el número (1234 en este caso) y almacenarlo en str?

This page sugiere que debo usar \d, pero ¿cómo?

Respuesta

17
$str =~ s/\D//g; 

Esto elimina todos los caracteres que no sean de la cadena. Eso es todo lo que necesitas hacer.

EDIT: Si los dígitos Unicode en otros scripts pueden estar presentes, una mejor solución es:

$str =~ s/[^0-9]//g; 
+1

Lazer solicita un número, no solo un número entero. Esta expresión regular arrojará '.',' e' que se puede usar para formar un flotador. También '\ d' no es solo' [0-9] ', debido al soporte Unicode en Perl: los dígitos en otros glifos (como el indio) son válidos. Entonces tu expresión regular también aceptará cadenas que no son números. – dolmen

+0

@dolmen Lazer debería ser más específico, entonces. Su ejemplo no incluye decimales ni exponenciales, y no puedo saber con certeza si quiere incluirlos o no. Sin embargo, tienes razón acerca de los dígitos del script variante unicode, voy a editar. –

26

Si no desea modificar la cadena original, puede extraer los números mediante la captura de ellos en el regex, utilizando subpatrones. En contexto de lista, una expresión regular devuelve las coincidencias definidas en los subpatrones.

my $str = 'abc 123 x456xy 789foo'; 

my ($first_num) = $str =~ /(\d+)/; # 123 
my @all_nums = $str =~ /(\d+)/g; # (123, 456, 789) 
+0

+1. Esto tiene la ventaja sobre mi respuesta de que no supone que haya un solo número incrustado en la cadena. –

1

En lo personal, yo lo haría así:

$s =~ /([0-9]+)/; 
print $1; 

$ 1 contendrá el primer grupo coincide con la expresión regular dada (la parte entre paréntesis).

+2

Nunca use el valor en '$ 1',' $ 2', etc. a menos que haya confirmado primero que su coincidencia fue exitosa. La variable de captura solo se (re) establece en una coincidencia exitosa, si '$ s' en tu ejemplo no tiene ningún dígito, obtendrás el resultado de tu última coincidencia. –

+0

Guau, qué tonto de mi parte. Gracias por la explicación. Solo para asegurarme de que aprenda mi lección ... ¿'(($ s = ~/([0-9] +) /) imprime $ 1' es la forma correcta de usar las variables de agrupación? – Ziggy

4

Si quieres hacerlo de manera destructiva, esta es la forma más rápida de hacerlo.

$str =~ tr/0-9//cd; 

tr anslate todos los caracteres del c omplement de 0-9 a nada, d ellos ELETE.

La advertencia de este enfoque, y de Phillip Potter, es que si hubiera otro grupo de dígitos más abajo en la cadena, se concatenarían con el primer grupo de dígitos. Entonces no está claro que quieras hacer esto.

La manera segura de conseguir uno y sólo un grupo de dígitos es

($str) = $str =~ /(\d+)/; 

El partido, en un contexto list devuelve una lista de capturas. Los pareados alrededor de $str son simplemente para poner la expresión en un contexto de lista y asignar la primera captura a $str.

+0

¡La mejor respuesta! – dolmen

Cuestiones relacionadas