use warnings; use strict; use Algorithm::Combinatorics 'variations_with_repetition'; use Test::More; my $re = qr{ \A ( .* ) ( (??{ length $1 ? "[^".quotemeta($1)."]" : "." }) ) ( (?: (?! \2 ) . )* ) \z }msx; for my $len (1..7) { my $iter = variations_with_repetition([qw/a b c/], $len); while ( my $c = $iter->next ) { my $str = join '', @$c; my $exp = do { my %h; $h{$_}++ for @$c; my %r = reverse %h; exists $r{1} }; is $str=~$re, $exp, $str.($exp?' =~':' !~').' re' or diag explain [ \%-, map [ $-[$_], eval "\$$_", $+[$_] ], 1..@+ ]; } } done_testing;