2009-05-23 15 views
7

正規表現の結果を出力すると、untilループを制御するために使用しようとしているときに、1またはnullが返されます。なぜ以下のコードは動作しませんが、5行目のコメントを外すとうまくいきますか?Perl正規表現が期待通りにループを終了しない

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]/); 
} 

しかし、私は無限ループから離れようとしています。

答えて

18

ここでの問題は、ループ内で$ channelSelectionを再宣言していることですが、ループの外側は古い値を保持しています。内側のループから "my"を削除します。

11

$channelSelectionはローカルでuntilループ内に再宣言しました。そうすれば、その値はループが実行されるたびに失われます。したがって、正規表現は一致しません。その場合、$channelSelectionの値は再び""に等しくなります。

ループ内からmyを削除すると問題が解決します。

+0

Heh、同じ回答、6秒間隔。 :) –

+0

はい、私はあなたにチェックをしたかったが、アルテムはそれほど速くなかった。 hehe良い仕事tho +1 – Copas

+0

それは素晴らしいです! :-) –

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__ 
+0

OPがモジュールのインストールにアクセスできる限り、これはもっと賢明な解決策です - Term :: Menuは標準のPerl distの一部ではありません。しかし、ニースの支援。 –

+0

残念なことに、このコードはperl 5.004_04を実行しているHP-UX 10.2で実行する必要があります。さらに悪いことに、これを更新する方法はほとんどありません(モジュールをインストールするのはずっと少ない)。私が働く業界では、1950年代の技術ではないものへのアップグレードを常に求めています。 – Copas

+0

@Artemまあ、OQはすでに答えられていたので、私は代替案を提示したかったのです。 BTW、http://perldoc.perl.org/perlfaq8.html#How-do-I-keep-my-own-module%2flibrary-directory%3fが役立つかもしれません。 –

3

ユーザーからの入力を得るための最良のソリューションは、IO :: Promptモジュールを使用することです。繰り返し、検証、メニューシステムなどをサポートしています。

+0

モジュールレビュー担当者が指摘している移植性の問題があるようです。 –

2

これはスタイル上の問題です(モジュールをインストールすることができないので、それは役に立ちません)。しかし、固定値をチェックするときに、正規表現を使用するのはおそらく最高のソリューション。これは

は、私がどうなるのかです:

use List::MoreUtils; 

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

# get $answer from prompt. 

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

は便利ないくつかの他の時間に来るかもしれません。

+0

これはもっと良い方法であると思われます(もしそうなら)。純粋なperl 5.004でそれを行う良い方法はありますか?クールなMODを表示していただきありがとうございます。 – Copas

+0

私はあなたがモジュールから機能を持ち上げ、それが機能するかどうかチェックすることができたと思います。それはほんの数行で、魔法をするようには見えません。 – Anon

関連する問題