use Set::CrossProduct; my $str = "ATC[TG]CC"; my $strings = []; my @wildcard; $str =~ s{ \[ ([ATCG]+) \] }{ push @wildcard, $1; "%s"; }xgem; # now your string looks like "ATC%sCC" if( @wildcard ) { my @set = map [ split //, $_ ], @wildcard; # now @set contains ( [ 'T', 'G' ] ) # and we weave each possible combination into the %s placeholders in $str my $xp = Set::CrossProduct->new( \@set ); while( my @tuple = $xp->get ) { push @$strings, sprintf $str, @tuple; } } else { push @$strings, $str; }