正则表达式用于定义语法。匹配和替换运算符检查字符串是否匹配使用正则表达式定义的语法模式。我不知道有任何工具使用正则表达式模式来生成字符串。
当您有任意数量的嵌套循环时,您需要Algorithm::Loops 的NestedLoops。在您的情况下,循环的数量是固定的,但有太多的循环,NestedLoops 无论如何都会派上用场。
[我假设您只对 ASCII 中的字母和数字感兴趣。]
Naïve(生成所有序列,并过滤掉不需要的序列):
use Algorithm::Loops qw( NestedLoops );
my @syms = ('A'..'Z', 'a'..'z', '0'..'9');
my $iter = NestedLoops([ (\@syms) x 8 ]);
while (my @s = $iter->()) {
my $s = join('', @s);
next if $s !~ /^[a-zA-Z][0-9]/;
next if $s =~ /[a-zA-Z]{4}|[0-9]{3}/;
say $s;
}
非常幼稚(生成除了明显不好的序列之外的所有序列,并过滤掉不需要的序列):
use Algorithm::Loops qw( NestedLoops );
my @letters = ('A'..'Z', 'a'..'z');
my @digits = ('0'..'9');
my @syms = (@letters, @digits);
my $iter = NestedLoops([
\@letters,
\@digits,
(\@syms) x 6,
]);
while (my @s = $iter->()) {
my $s = join('', @s);
next if $s =~ /[a-zA-Z]{4}|[0-9]{3}/;
say $s;
}
但这仍然会产生很多需要丢弃的字符串。下面只生成我们想要的字符串。它通过生成将产生所需字符串的模式(LDLLLDLL、LDLLLDLD、LDLLLDDL、LDLLDLLL、...),然后从这些模式构建字符串。
高效算法(不代表实现高效):
use Algorithm::Loops qw( NestedLoops );
my @letters = ('A'..'Z', 'a'..'z');
my @digits = ('0'..'9');
sub make_pat_gen_iter {
my $raw_pat_gen_iter = NestedLoops([
['L'],
['D'],
(['L','D']) x 6,
]);
return sub {
while (1) {
my @pat = $raw_pat_gen_iter->();
return () if !@pat;
my $pat = join('', @pat);
next if $pat =~ /L{4}|D{3}/;
return @pat;
}
};
}
sub make_gen_iter {
my $pat_gen_iter = make_pat_gen_iter();
my @pat;
my $gen_sub_iter;
return sub {
return () if !$pat_gen_iter;
while (1) {
if (!$gen_sub_iter) {
@pat = $pat_gen_iter->();
if (!@pat) {
$pat_gen_iter = undef;
return ();
}
$gen_sub_iter = NestedLoops([
map { $_ eq 'L' ? \@letters : \@digits } @pat
]);
}
my @s = $gen_sub_iter->();
if (!@s) {
$gen_sub_iter = undef;
next;
}
return join('', @s);
}
};
}
my $gen_iter = make_gen_iter();
while (defined( my $s = $gen_iter->() )) {
say $s;
}
为了好玩,下面是模式迭代器的完整结果:
LDLLLDLL LDLLLDLD LDLLLDDL LDLLDLLL LDLLDLLD
LDLLDLDL LDLLDLDD LDLLDDLL LDLLDDLD LDLDLLLD
LDLDLLDL LDLDLLDD LDLDLDLL LDLDLDLD LDLDLDDL
LDLDDLLL LDLDDLLD LDLDDLDL LDLDDLDD LDDLLLDL
LDDLLLDD LDDLLDLL LDDLLDLD LDDLLDDL LDDLDLLL
LDDLDLLD LDDLDLDL LDDLDLDD LDDLDDLL LDDLDDLD