使用正则表达式打印字母数字字符

时间:2015-01-05 12:37:56

标签: regex perl shell

我是正则表达的新手。

我需要按照以下模式打印所有组合8个字符(字母数字)。

  • 第一个字符必须是字母
  • 第二个字符必须为数字
  • 不得有3个连续的数字字符
  • 不得有4个连续的字母字符

2 个答案:

答案 0 :(得分:1)

正则表达式用于定义语法。匹配和替换运算符检查字符串是否与使用正则表达式定义的语法模式匹配。我不知道任何使用正则表达式模式生成字符串的工具。


如果您有任意数量的嵌套循环,则需要Algorithm::LoopsNestedLoops。在你的情况下,有一个固定数量的循环,但有许多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;
}

但是仍然会产生很多需要丢弃的字符串。以下只生成我们想要的字符串。它通过生成将产生所需字符串的模式(LDLLLDLLLDLLLDLDLDLLLDDLLDLLDLLL,...)来实现,然后根据这些模式构建字符串。< / p>

高效算法(并不意味着实施效率很高):

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

答案 1 :(得分:0)

您可以检查每个模式。 让我们将字符串命名为 $ str 。从&#34; 00000000&#34;生成 $ str 到&#34; zzzzzzzz&#34;并使用 if 子句来获取与模式匹配的字符串。

if ($str =~ /^[A-Za-z][0-9]/        // pattern 1 and 2
  && $str !~ /[0-9]{3}/             // pattern 3
  && $str !~ /[A-Za-z]{4}/)         // pattern 4