Perl正则表达式没有像预期的那样突破到循环

时间:2009-05-23 19:20:56

标签: regex perl

当我打印我试图用来控制until循环的正则表达式的结果时,它给我1或者我期待的null。为什么下面的代码不起作用,但如果我取消注释第五行它可以正常工作?

print("Please enter 1, 2, 3 or 4 : ");
my $channelSelection = "";

until ($channelSelection =~ /^[1-4]$/) {
    chomp(my $channelSelection = <STDIN>);
    #last if ($channelSelection =~ /^[1-4]$/);
    print ("Invalid choice ($channelSelection) please try again: ") 
        if ($channelSelection !~ /[1-4]/);
}

我确信这已在其他地方得到解决,但无法通过搜索找到它。把我指向正确的方向会很棒。

我通常会做类似的事情。

print("Please enter 1, 2, 3 or 4 : ");
my $channelSelection = "";
while (1) {
    chomp(my $channelSelection = <STDIN>);
    last if ($channelSelection =~ /^[1-4]$/);
    print ("Invalid choice ($channelSelection) please try again: ") if ($channelSelection !~ /[1-4]/);
}

但我正试图摆脱无限循环。

5 个答案:

答案 0 :(得分:18)

这里的问题是你在循环中重新声明$ channelSelection,但循环外部保留旧值。从内循环中删除“我的”。

答案 1 :(得分:11)

您已在until循环中本地重新声明$channelSelection。这样,每次循环执行时它的值都会丢失。因此正则表达式将不匹配,因为$channelSelection的当时值将再次等于""

从循环中删除my将解决问题。

答案 2 :(得分:6)

怎么不担心呢?

#!/usr/bin/perl

use strict;
use warnings;

use Term::Menu;

my @channels = qw( 1 2 3 4 );

my $prompt = Term::Menu->new(
    aftertext => 'Please select one of the channels listed above: ',
    beforetext => 'Channel selection:',
    nooptiontext =>
        "\nYou did not select a valid channel. Please try again.\n",
    toomanytries =>
        "\nYou did not specify a valid channel, going with the default.\n",
    tries => 3,
);

my $answer = $prompt->menu(
    map { $_ => [ "Channel $_" => $_ ] } @channels
);

$answer //= $channels[0];

print "$answer\n";

__END__

答案 3 :(得分:3)

从用户获取输入的最佳解决方案是使用IO :: Prompt模块。它支持重复,验证,菜单系统等等。

答案 4 :(得分:2)

这更像是一个样式问题(因为你无法安装模块,它对你没有帮助),但我只是想指出,在检查固定值时,使用正则表达式可能不是最好的溶液

这就是我要做的事情:

use List::MoreUtils;

my @allowed_values = qw( 1 2 3 4 );

# get $answer from prompt.

if(any { $_ == $answer } @allowed_values) {
    # All is good.
}

可能会在其他时间派上用场。