如果我有一个包含以下内容的文本文件:
Today (is|will be) a (great|good|nice) day.
有一种简单的方法可以生成随机输出,如:
Today is a great day.
Today will be a nice day.
使用Perl或UNIX utils?
闭包很有趣:
#!/usr/bin/perl
use strict;
use warnings;
my @gens = map { make_generator($_, qr~\|~) } (
'Today (is|will be) a (great|good|nice) day.',
'The returns this (month|quarter|year) will be (1%|5%|10%).',
'Must escape %% signs here, but not here (%|@).'
);
for ( 1 .. 5 ) {
print $_->(), "\n" for @gens;
}
sub make_generator {
my ($tmpl, $sep) = @_;
my @lists;
while ( $tmpl =~ s{\( ( [^)]+ ) \)}{%s}x ) {
push @lists, [ split $sep, $1 ];
}
return sub {
sprintf $tmpl, map { $_->[rand @$_] } @lists
};
}
Run Code Online (Sandbox Code Playgroud)
输出:
C:\Temp> h Today will be a great day. The returns this month will be 1%. Must escape % signs here, but not here @. Today will be a great day. The returns this year will be 5%. Must escape % signs here, but not here @. Today will be a good day. The returns this quarter will be 10%. Must escape % signs here, but not here %. Today is a good day. The returns this month will be 1%. Must escape % signs here, but not here %. Today is a great day. The returns this quarter will be 5%. Must escape % signs here, but not here @.
小智 7
码:
#!/usr/bin/perl
use strict;
use warnings;
my $template = 'Today (is|will be) a (great|good|nice) day.';
for (1..10) {
print pick_one($template), "\n";
}
exit;
sub pick_one {
my ($template) = @_;
$template =~ s{\(([^)]+)\)}{get_random_part($1)}ge;
return $template;
}
sub get_random_part {
my $string = shift;
my @parts = split /\|/, $string;
return $parts[rand @parts];
}
Run Code Online (Sandbox Code Playgroud)
逻辑:
my $template = ...)for ...)pick_one来做这项工作"(...)"子串,并用随机部分替换它们($template =~ s...)获取随机部分很简单:
my $string = shift)|character(my @parts = ...)拆分它return $parts[...)这基本上都是.您可以将相同的逻辑放入其中s{}{},而不是使用函数,但它可读性稍差:
$template =~ s{\( ( [^)]+ ) \)}
{ my @parts = split /\|/, $1;
$parts[rand @parts];
}gex;
Run Code Online (Sandbox Code Playgroud)
听起来你可能正在寻找Regexp :: Genex.从模块的概要:
#!/usr/bin/perl -l
use Regexp::Genex qw(:all);
$regex = shift || "a(b|c)d{2,4}?";
print "Trying: $regex";
print for strings($regex);
# abdd
# abddd
# abdddd
# acdd
# acddd
# acdddd
Run Code Online (Sandbox Code Playgroud)