Perl - 将字符串扩展到列表中。
Perl - Expand a string into a list.
正在尝试执行如下操作。
#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 可能有更简单的方法我可以别想了
给出表单的输入
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 = ;
length($var)
or die("Empty \"[]\"\n");
$dict{$var}
or die("Unknown var \"$var\"\n");
push @loops, $dict{$var};
redo;
}
if (/\G ( [^\[]+ ) /xgc) {
push @loops, [ ];
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 = ;
length($var)
or die("Empty \"[]\"\n");
$dict{$var}
or die("Unknown var \"$var\"\n");
$glob .= $dict{$var};
redo;
}
if (/\G ( [^\[]+ ) /xgc) {
$glob .= ;
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)]|(.)/?"\Q":?"{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
正在尝试执行如下操作。
#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 可能有更简单的方法我可以别想了
给出表单的输入
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 = ;
length($var)
or die("Empty \"[]\"\n");
$dict{$var}
or die("Unknown var \"$var\"\n");
push @loops, $dict{$var};
redo;
}
if (/\G ( [^\[]+ ) /xgc) {
push @loops, [ ];
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 = ;
length($var)
or die("Empty \"[]\"\n");
$dict{$var}
or die("Unknown var \"$var\"\n");
$glob .= $dict{$var};
redo;
}
if (/\G ( [^\[]+ ) /xgc) {
$glob .= ;
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)]|(.)/?"\Q":?"{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