我无法对从标准输入获取的输入应用perl范围运算符。这是代码:
#!/usr/bin/perl
@range = (1..5, 6, 7, 8..10);
print "@range\n";
print "Enter your range. Esc by CTRL+D.\n";
chomp(@user_range = <STDIN>); # input 1..5<LF> 6<LF> 7..10<LF> CTRL+D
print "@user_range\n";
第一个代码块(@range)工作正常和输出:1 2 3 4 5 6 7 8 9 10; 在秒(@user_range)我输入1..5 6 7..10 CTRL + D 。我得到的输出是1..5 6 7..10 而不是1 2 3 4 5 6 7 8 9 10.
请帮忙。
答案 0 :(得分:4)
您从STDIN
或任何其他文件句柄中读取的任何内容都只是一个字符串。这是一项基本的安全措施,您不希望您的编程语言将输入评估为代码。
你可以通过eval
运行它,但那是一个安全漏洞;它允许用户运行任意代码。 不要使用eval STRING
,除非您知道自己在做什么。 eval BLOCK
很好,它完全不同。
相反,如果你想要做一些事情来输入你,你必须自己做。如果它只是简单的数字,那么它可以相当简单。
use 5.010;
use strict;
use warnings;
# Read the string from input and remove the newline.
my $list_string = <STDIN>;
chomp $list_string;
# Split it into a list on commas.
# "1..5, 6, 7..10" becomes "1..5", "6", "7..10".
my @list = split /\s*,\s*/, $list_string;
# Go through each element checking for a range operator.
# If there's a range operator, replace it with the range.
# Otherwise leave it alone.
@list = map { range_transform($_) } @list;
print join ", ", @list;
sub range_transform {
my $string = shift;
# Match the X..Y. If it doesn't match, just return it.
return $string unless $string =~ m{^(\d+)\.\.(\d+)$};
# Perform the range operation.
return $1..$2;
}
这没有任何错误检查,它也应该检查输入是一个数字还是一个范围操作符,如果它是其他任何东西就呕吐。但这应该让你开始。