use Test::More; my @match_wanted = qw( abc bca cab cba bac acb ); my @match_unwanted = qw( aab abbc acc ); sub match { my $s = shift; return ( ($s =~ /(?:[abc].*){3}/) && ! ($s =~ /([abc]).*\1/) ); } plan 'tests' => ( scalar @match_wanted + scalar @match_unwanted ); ok( match( $_ ), "matches '$_'" ) for @match_wanted; ok( ! match( $_ ), "does not match '$_'" ) for @match_unwanted;