解析使用同义词的文件

Lin*_*Lin 0 unix random perl

如果我有一个包含以下内容的文本文件:

    Today (is|will be) a (great|good|nice) day.

有一种简单的方法可以生成随机输出,如:

    Today is a great day.
    Today will be a nice day.

使用Perl或UNIX utils?

Sin*_*nür 8

闭包很有趣:

#!/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)

逻辑:

  1. 定义输出模板(my $template = ...)
  2. 输入循环多次打印随机输出(for ...)
  3. 打电话pick_one来做这项工作
  4. 找到所有"(...)"子串,并用随机部分替换它们($template =~ s...)
  5. 打印生成的字符串

获取随机部分很简单:

  1. 接收提取的子串(my $string = shift)
  2. |character(my @parts = ...)拆分它
  3. 返回随机部分(return $parts[...)

这基本上都是.您可以将相同的逻辑放入其中s{}{},而不是使用函数,但它可读性稍差:

$template =~  s{\( ( [^)]+ ) \)}
               { my @parts = split /\|/, $1;
                 $parts[rand @parts];
               }gex;
Run Code Online (Sandbox Code Playgroud)


Dav*_*man 6

听起来你可能正在寻找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)