0
$str = '[Hi|Hello|Aloha] [Kate|Ann|Polly]';

str のランダムなバリエーションを出力する関数が必要です。例えば:

Hi Ann
Hello Polly
....
....

アニーのアイデア?

4

4 に答える 4

4
$str = '[Hi|Hello|Aloha] [Kate|Ann|Polly]';

$str =~ s{
    \[ ( [^\]]* ) \]
}{
    my @choices = split /\|/, $1;
    $choices[rand(@choices)]
}xeg;

say $str;
于 2012-09-15T11:50:24.013 に答える
2

セットから 2 つの乱数を生成し、{0,1,2}それぞれのグリーティングを作成するだけです。例: 生成された数値が12の場合、 を出力します'Hello Polly'2との場合0'Aloha Kate'.

于 2012-09-15T10:41:45.330 に答える
1

これを行うには、リストとリスト パッケージを使用しshuffleますpairwise

use 5.010;
use List::Util qw /shuffle/;
use List::MoreUtils qw/pairwise/;

$, = " ";

@greetings = shuffle qw(Hi Hello Aloha);
@names     = shuffle qw(Kate Ann Polly);

pairwise { say $a, $b } @greetings, @names;

出力例:

Hello Polly
Aloha Ann
Hi Kate

文字列形式に固執している場合は、次のような方法でリストに変換できます。

$str = '[Hi|Hello|Aloha] [Kate|Ann|Polly]';
($greetings, $names) = $str =~ /\[([^]]+)\] +\[([^]]+)\]/;

@greetings = shuffle split /\|/, $greetings;
@names     = shuffle split /\|/, $names;
于 2012-09-15T12:02:02.610 に答える
0

2 つの配列から 2 つのランダムな要素を組み合わせることはかなり簡単で、@OleksandrBondarenko によって回答されています。さらに興味深いのは、その文字列からデータ構造を取得する方法です。

可能性 1

入力形式を変更します。文字列ではなく、2 つのリスト/配列が必要です。API またはインターフェースを変更できる場合は、この文字列表現を使用するよりも簡単かもしれません。

可能性 2

その文字列とそれから Perl コードを作成しますeval。これは簡単ですが、これは重大なセキュリティ上の問題であるため、入力がよく知られていて信頼できる 1 回限りの問題にのみ適用する必要があります。

my $str = '[Hi|Hello|Aloha] [Kate|Ann|Polly]';
$str =~ s/ /,/g;            # '[Hi|Hello|Aloha],[Kate|Ann|Polly]'
$str =~ s/\|/","/g;         # '[Hi","Hello","Aloha],[Kate","Ann","Polly]'
$str =~ s/\[/["/g;          # '["Hi","Hello","Aloha],["Kate","Ann","Polly]'
$str =~ s/\]/"]/g;          # '["Hi","Hello","Aloha"],["Kate","Ann","Polly"]'
my @arrayrefs = eval $str;  # (["Hi","Hello","Aloha"],["Kate","Ann","Polly"])
my @greetings = @{shift @arrayrefs};
my @names     = @{shift @arrayrefs};

文字列には任意のコードが含まれている可能性があり、コンピューター、ファイル、またはセキュリティに深刻な損害を与える可能性があるため、製品コードではこれを行わないでください。

可能性 3

データを正しく処理および解析します。これは難しい場合もありますが、最も安全な解決策です。

my $str = '[Hi|Hello|Aloha] [Kate|Ann|Polly]';
my @strings = split /(?<=\])\s+(?=\[)/, $str;
# for each $string in @strings:
$string =~ s/^\[//;  # 
$string =~ s/\]$//;  # or: $string = substr $str, 1, length $str -2;
my @parts = split /\|/, $string

1 つ目@partsは挨拶の配列で、2 つ目は名前の配列です。このソリューションには、省略したコードがさらに必要です。

最初の正規表現のルックアラウンドはsplit実際には必要ありませんが、データ形式について推測するよりはましです。

于 2012-09-15T11:16:36.723 に答える