我有一个Perl应用程序,它从命令行输入:

application --fields 1-6,8

我需要在命令行上显示用户请求的字段。

我想用'...'代替' - ',以便我可以将它们存储在数组中,例如

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

这里的问题是@arr工作正常(应该如此),但在@ arr2中,整个字符串不会扩展为数组元素。

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

可以这样做吗?

有帮助吗?

解决方案

如果这是用户输入,如果您有任何安全问题,请不要在其上使用字符串eval。

请尝试使用 Number :: Range

 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

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

 use Set::IntSpan;

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

但是它要求范围是有序的和不重叠的(它是为了在.newsrc文件上使用而编写的,如果有人记得它们是什么的话)。它还允许无限范围(字符串开始 - 数字或结束数字 - ),元素方法将会呱呱叫。

其他提示

您正在考虑 @ arr2 = eval($ str); 由于您正在接受输入并对其进行评估,因此您需要小心。 您应该 @ arr2 = eval($ str)if($ str = ~m / ^ [0-9。,] + $ /)

P.S。我不知道Number :: Range包,但它是太棒了。 Number :: Range ftw。

我在处理Bit :: Vector :: to_Enum的输出时遇到了同样的问题。我解决了这个问题:

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

然后也在我的文件中:

sub expand_range
{
    return join(",",(

我在处理Bit :: Vector :: to_Enum的输出时遇到了同样的问题。我解决了这个问题:

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

然后也在我的文件中:

<*>

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

我非常努力地将这个扩展放在s //的第二部分//所以我不需要额外的功能,但我无法让它工作。我喜欢这个,因为虽然Number :: Range可以工作,但这样我就不必为另一个模块提供一些应该是微不足道的东西了。

[0] ..

我在处理Bit :: Vector :: to_Enum的输出时遇到了同样的问题。我解决了这个问题:

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

然后也在我的文件中:

<*>

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

我非常努力地将这个扩展放在s //的第二部分//所以我不需要额外的功能,但我无法让它工作。我喜欢这个,因为虽然Number :: Range可以工作,但这样我就不必为另一个模块提供一些应该是微不足道的东西了。

[1])); }

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

我非常努力地将这个扩展放在s //的第二部分//所以我不需要额外的功能,但我无法让它工作。我喜欢这个,因为虽然Number :: Range可以工作,但这样我就不必为另一个模块提供一些应该是微不足道的东西了。

@arr2 = ( eval $str ) ;

工作,当然你必须非常小心eval()。

您可以使用eval:

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

虽然这是用户输入,但您可能希望首先对输入字符串进行一些验证,以确保它们没有输入任何狡猾的内容。

使用拆分:

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

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

你不能只在一个数组中放一个包含','的字符串,并期望它转向元素(除非你使用一些Perl黑魔法,但我们不会在这里讨论)

但是Regex和split是你的朋友。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top