Pergunta

Tenho uma aplicação Perl que leva a partir de linha de comando de uma entrada como:

application --fields 1-6,8

eu sou obrigado a exibir os campos conforme solicitado pelo usuário na linha de comando.

Eu pensei de substituir '-' com '..' para que eu possa armazená-los em ordem por exemplo

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

O problema aqui é que @arr funciona bem (como deveria), mas em @ ARR2 toda a cadeia não é expandido como elementos da matriz.

Eu tentei usar sequências de escape, mas sem sorte.

Pode ser feito dessa maneira?

Foi útil?

Solução

Se esta é a entrada do usuário, não use eval corda nele se você tiver quaisquer preocupações de segurança em tudo.

Tente usar Número :: Faixa vez:

 use Number::Range;

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

Para evitar a morte em um intervalo inválido, faça:

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

Há também Set :: IntSpan , que utiliza - em vez de ..:

 use Set::IntSpan;

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

mas exige os intervalos estar em ordem e não-sobreposição (que foi escrito para uso em arquivos .newsrc, se alguém se lembra o que aqueles são). Ele também permite infinitas faixas (onde a string começa - número ou extremidades número -)., Que o método de elementos vai coaxar on

Outras dicas

Você está pensando @arr2 = eval($str); Desde que você está tomando entrada e avaliar isso, você precisa ter cuidado. Você deve provavelmente @arr2 = eval($str) if ($str =~ m/^[0-9.,]+$/)

P.S. Eu não sabia sobre o pacote de número :: Range, mas de incrível . Número :: Faixa ftw.

Eu tive o mesmo problema em lidar com a saída do Bit :: Vector :: to_Enum. Eu resolvi fazendo:

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

, em seguida, também no meu arquivo:

sub expand_range
{
    return join(",",($_[0] .. $_[1]));
}

Assim, "1,3,5-7,9,12-15" se transforma em "1,3,5,6,7,9,12,13,14,15".

Eu tentei realmente difícil colocar que a expansão na 2ª parte do s /// então eu não precisaria de que a função extra, mas eu não poderia fazê-lo funcionar. I como este, porque enquanto Número :: Faixa iria funcionar, desta forma eu não ter que puxar em outro módulo para algo que deve ser trivial.

@arr2 = ( eval $str ) ;

Works, embora, naturalmente, você tem que ter muito cuidado com eval ().

Você pode usar eval:

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

Apesar de se isto é a entrada do usuário, você provavelmente vai querer fazer alguma validação sobre a cadeia de entrada em primeiro lugar, para se certificar de que eles não têm entrada desonesto nada.

Use dividido:

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

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

Você não pode simplesmente colocar uma string contendo '' em uma matriz, e esperar que ele vire a elementos (exceto se você usar alguma magia negra Perl, mas não vamos entrar em detalhes aqui)

Mas Regex e divisão são seus amigos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top