如何展开,如“1..15,16”的字符串到数字的列表?(How can I expand a str

2019-06-23 16:15发布

我有一个Perl应用程序,从命令线的输入如需要:

application --fields 1-6,8

我需要通过命令行用户的要求显示的字段。

我想代的“ - ”与“..”,这样我可以将它们存储在阵列上,比如

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

这里的问题是,@arr工作正常(因为它应该),但在@ ARR2整个字符串不扩大为数组元素。

我一直在使用转义序列,但没有运气尝试。

能不能做到这样?

Answer 1:

如果这是用户的输入,勿使用字符串的eval如果您有任何的所有安全问题。

尝试使用数量::范围 ,而不是:

 use Number::Range;

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

为了避免死在了无效的范围,这样做:

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

还有集:: IntSpan ,它使用-而不是..:

 use Set::IntSpan;

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

但它需要的范围是为了和非重叠(这是对.newsrc文件使用书面,如果有人还记得那些是什么)。 它还允许无限的范围(其中,字符串开始- 或结束 - ),其中所述元件的方法将在叫上。



Answer 2:

你在想的@arr2 = eval($str); 既然你正在做的输入和评价,你要小心。 你应该@arr2 = eval($str) if ($str =~ m/^[0-9.,]+$/)

PS我不知道该号码::范围包,但它的真棒 。 数::量程FTW。



Answer 3:

我在处理位的输出::矢量:: to_Enum有同样的问题。 我解决了它这样做:

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

然后也是在我的文件:

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

因此,“1,3,5-7,9,12-15”变成“1,3,5,6,7,9,12,13,14,15”。

我想真的很难把该扩展在S ///所以我不会需要额外功能的第二部分,但我无法得到它的工作。 我喜欢这个,因为当数::范围会的工作,这样我就不必在另一个模块拉的东西,应该是微不足道的。



Answer 4:

@arr2 = ( eval $str ) ;

作品,但当然,你必须非常小心的eval()。



Answer 5:

你可以使用eval:

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

虽然如果这是用户输入的,你可能会想要做输入字符串一些验证第一,以确保他们没有任何输入狡猾。



Answer 6:

使用拆分:

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

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

你不能只是把包含字符串“”在数组中,并期望它转向元素(除非你使用一些Perl的黑魔法,但我们不会进入这里)

但是,正则表达式和分裂,是你的朋友。



文章来源: How can I expand a string like “1..15,16” into a list of numbers?