Pregunta

Tengo una aplicación Perl que toma de la línea de comando una entrada como:

application --fields 1-6,8

Estoy obligado a mostrar los campos solicitados por el usuario en la línea de comandos.

Pensé en sustituir '-' con '..' para poder almacenarlos en una matriz, por ejemplo,

$str = "1..15,16" ;
@arr2 = ( $str ) ;
@arr = ( 1..15,16 ) ;
print "@arr\n" ;
print "@arr2\n" ;

El problema aquí es que @arr funciona bien (como debería) pero en @ arr2 la cadena completa no se expande como elementos de matriz.

He intentado usar secuencias de escape pero no tuve suerte.

¿Se puede hacer de esta manera?

¿Fue útil?

Solución

Si esto es una entrada del usuario, no use la evaluación de cadena en él si tiene algún problema de seguridad.

Intente usar Number :: Range en su lugar:

 use Number::Range;

 $str = "1..15,16" ;
 @arr2 = Number::Range->new( $str )->range;
 print for @arr2;

Para evitar morir en un rango no válido, haga:

 eval { @arr2 = Number::Range->new( $str )->range; 1 } or your_error_handling

También hay Set :: IntSpan , que usa - en lugar de ..:

 use Set::IntSpan;

 $str = "1-15,16";
 @arr2 = Set::IntSpan->new( $str )->elements;

pero requiere que los rangos estén en orden y sin superposición (se escribió para su uso en archivos .newsrc, si alguien recuerda cuáles son). También permite rangos infinitos (donde la cadena comienza - número o termina con número -), que el método de los elementos graznará.

Otros consejos

Estás pensando en @ arr2 = eval ($ str); Dado que está tomando aportaciones y evaluando eso, debe tener cuidado. Probablemente debería @ arr2 = eval ($ str) if ($ str = ~ m / ^ [0-9.,] + $ /)

P.S. No sabía sobre el paquete Number :: Range, pero es impresionante . Number :: Range ftw.

Tuve el mismo problema al tratar con la salida de Bit :: Vector :: to_Enum. Lo resolví haciendo:

$range_string =~ s/\b(\d+)-(\d+)\b/expand_range($1,$2)/eg;

luego también en mi archivo:

sub expand_range
{
    return join(",",(

Tuve el mismo problema al tratar con la salida de Bit :: Vector :: to_Enum. Lo resolví haciendo:

$range_string =~ s/\b(\d+)-(\d+)\b/expand_range($1,$2)/eg;

luego también en mi archivo:

<*>

Entonces " 1,3,5-7,9,12-15 " se convierte en "1,3,5,6,7,9,12,13,14,15".

Intenté realmente poner esa expansión en la segunda parte de s /// para no necesitar esa función extra, pero no pude hacer que funcionara. Me gusta esto porque si bien Number :: Range funcionaría, de esta manera no tengo que extraer otro módulo para algo que debería ser trivial.

[0] ..

Tuve el mismo problema al tratar con la salida de Bit :: Vector :: to_Enum. Lo resolví haciendo:

$range_string =~ s/\b(\d+)-(\d+)\b/expand_range($1,$2)/eg;

luego también en mi archivo:

<*>

Entonces " 1,3,5-7,9,12-15 " se convierte en "1,3,5,6,7,9,12,13,14,15".

Intenté realmente poner esa expansión en la segunda parte de s /// para no necesitar esa función extra, pero no pude hacer que funcionara. Me gusta esto porque si bien Number :: Range funcionaría, de esta manera no tengo que extraer otro módulo para algo que debería ser trivial.

[1])); }

Entonces " 1,3,5-7,9,12-15 " se convierte en "1,3,5,6,7,9,12,13,14,15".

Intenté realmente poner esa expansión en la segunda parte de s /// para no necesitar esa función extra, pero no pude hacer que funcionara. Me gusta esto porque si bien Number :: Range funcionaría, de esta manera no tengo que extraer otro módulo para algo que debería ser trivial.

@arr2 = ( eval $str ) ;

Funciona, aunque, por supuesto, debes tener mucho cuidado con eval ().

Puede usar eval:

$str = "1..15,16" ;
@arr2 = ( eval $str ) ;
@arr = ( 1..15,16 ) ;
print "@arr\n" ;
print "@arr2\n" ;

Aunque si esto es una entrada del usuario, es probable que primero desee hacer una validación en la cadena de entrada, para asegurarse de que no haya ingresado nada dudoso.

Usar división:

@parts = split(/\,/, $fields);

print $parts[0];
1-6
print $parts[1];
8

No puede simplemente poner una cadena que contenga ',' en una matriz, y esperar que se convierta en elementos (excepto si usa algo de magia negra Perl, pero no entraremos en eso aquí)

Pero Regex y split son tus amigos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top