2016-03-23 5 views
-3

次のような処理をしようとしています。Perl - 文字列をリストに展開します。

#expand [a] to is, and isn't 
#expand [b] to test, and demo 
my $string = 'This [a] a [b]'; 

ので、基本的に、私は

my @strings = ('This is a test', 'This isn\'t a test', 'This is a demo', 'This isn\'t a demo'); 

で終わるだろう、私は再帰を使用する前にこれをやったが、それは、データの非常に大きなセットとがあるかもしれないように私は感じたルールの多くにありましたMapやgrepやList :: MoreUtilsを使った方が簡単です。私はそれについて考えることはできません。フォームの

+0

でしょうあなたは 'sのを/使用することを含むために受け入れソリューション\ [a \] /は '$ string'にありますか? –

+0

それは私の元の文字列を変更するだけでしょうか。 –

+0

あなたは "sprintf"を探しているようですが、もしあなたが "[a]"のものと結婚していなければ。 – AKHolland

答えて

2

考えると入力

my %dict = (
    a => ["is", "isn't"], 
    b => ["test", "demo"], 
); 

my $template = 'This [a] a [b]'; 

アルゴリズム::ループバージョン:

use Algorithm::Loops qw(NestedLoops); 

my @loops; 
for ($template) { 
    if (/\G \[ /xgc) { 
     /\G ([^\]]*) \] /xgc 
     or die("Missing \"]\"\n"); 

     my $var = $1; 
     length($var) 
     or die("Empty \"[]\"\n"); 

     $dict{$var}  
     or die("Unknown var \"$var\"\n"); 

     push @loops, $dict{$var}; 
     redo; 
    } 

    if (/\G ([^\[]+) /xgc) { 
     push @loops, [ $1 ]; 
     redo; 
    } 

    /\G \z /xgc 
     or die("Internal error"); 
} 

my $iter = NestedLoops(\@loops); 
while (my @parts = $iter->()) { 
    print(join('', @parts), "\n"); 
} 

出力:

This is a test 
This is a demo 
This isn't a test 
This isn't a demo 

globベースのバージョン:エラーチェックがなければ、その特定の辞書のための

$_ = '{'.join(',', map quotemeta($_), @$_).'}' 
    for values(%dict); 

my $glob; 
for ($template) { 
    if (/\G \[ /xgc) { 
     /\G ([^\]]*) \] /xgc 
     or die("Missing \"]\"\n"); 

     my $var = $1; 
     length($var) 
     or die("Empty \"[]\"\n"); 

     $dict{$var} 
     or die("Unknown var \"$var\"\n"); 

     $glob .= $dict{$var}; 
     redo; 
    } 

    if (/\G ([^\[]+) /xgc) { 
     $glob .= $1; 
     redo; 
    } 

    /\G \z /xgc 
     or die("Internal error"); 
} 

while (defined(my $string = glob($glob))) { 
    print($string, "\n"); 
} 

、これはかなり縮小することができます。

$ perl -E'say for glob shift=~s/\[((a)|b)]|(.)/$3?"\Q$3":$1?"{is,isn'\''t}":"{test,demo}"/serg' \ 
    'This [a] a [b]' 
This is a test 
This is a demo 
This isn't a test 
This isn't a demo 
+0

これは私の最初の試みとほぼ同じです。私はちょうどそれを再利用すると思います。私は1つのライナーソリューションが存在することを期待していました。 –

+0

独自のテンプレートシステムを作成すると、オンライナーを期待できません。 – ikegami

+0

ありがとう、あなたは私が返信したいと思っていた人です。 –

関連する問題