1

主に言語を学ぶために、Perl で小さなユーティリティ スクリプトを開発しています。スクリプトには、アクション ディスパッチャとして機能するメイン関数と、それぞれ 1 つの特定のタスクを実行する多数の小さなアクション ルーチンがあります (今日の年の印刷、7 日以上経過したファイルのカウントなど)。ユーザーは、「./myscript doy」、「./myscript doy 01/01/2013」、「./myscript ls /home/test gt 7 days」などの構文を使用してスクリプトを呼び出します。一般的には、「./ myscript アクション [パラメーターとキーワードの組み合わせ]". キーワードは「より小さい」、「より大きい」などです。ターゲット アクションは、キーワードが変更されても (親アクションのキーワードに基づいて if..else を実行するのではなく) 異なる可能性があります。

ディスパッチテーブルは次のようなハッシュです

my %Actions =
(   # Syntax => [RegEx, Description, Function]
    'help' => ['help', 'Displays this help', \&PrintHelp],
    'doy' => ['doy', 'Day of Year', \&DayOfYear],
    'doy <dd/mm/yyyy>' => ['doy (\d{2}/\d{2}/\d{4})', 'Day of Year for a date', \&DayOfYearForDate]
)

ハッシュのキーは、コマンド構文そのものです (説明とともにヘルプの一部としてユーザーに表示されます)。RegEx は、コマンド ライン引数 (結合) と比較して、要求されたアクションを決定するために使用されます。

ここで、アクション ルーチンの負担を軽減するために、メイン関数内でパラメーターの配列も作成し、これを引数としてアクション ルーチンに渡したいと考えています。したがって、「./myscript ls /home/test gt 7 days」のようなコマンド ラインは、@args = ['/home/test', 7] になります。問題は、@args に挿入される有効な後方参照 ($1、$2、...) の数を特定する方法を見つけられなかったことです。もちろん、アクションごとに予想されるパラメーター数は知っていますが、意図はそれを一般的なものにすることです。私が見つけた 1 つのオプションは、「if (defined ${$i})」のような範囲 (1..10) をチェックすることでした。これをループで使用すると、「use strict」オプションでは機能しません。一致するパラメーターをキャプチャしてアクションに渡すためのより良い方法があるかどうかを提案してください。

4

1 に答える 1

3

後方参照は、以前にキャプチャされたもの (例: \1) に一致する正規表現命令です。実際には、キャプチャの数が必要です ( (...))。

正規表現の一致はリスト コンテキストでキャプチャしたものを返すため、それらをカウントするだけで済みます。

my @captures = $str =~ /.../;
my $count = @captures;

また

my $count = my @captures = $str =~ /.../;

また

my $count = () = $str =~ /.../;

も確認でき@-ます。

my $count = /.../ ? $#- : undef;
于 2013-06-19T09:17:17.587 に答える