my $string = "AAATTTAGTTCTTAAGGCTGACATCGGTTTACGTCAGCGTTACCCCCCAAGTTATTGGGGACTTT"; my %expect = qw( CCCCCC 1 GGGG 1 AAA 1 TTT 3 AA 2 GG 2 TT 5 ); use Test::More; use Benchmark qw(cmpthese); my %subs; sub v1 { %subs = (); $subs{$_}++ for grep { length >= 2 } split m/,/ => ($string =~ s/([ACGT])\K(?!\1)/,/gr); } # v1 sub v2 { %subs = (); $subs{$_}++ for grep m/^([ACGT])\1+$/ => split m/,/ => ($string =~ s/(\w)\K(?!\1)/,/gr); } # v2 sub v3 { %subs = (); $subs{$_}++ for $string =~ m/(AA+|CC+|GG+|TT+)/g; } # v3 sub v4 { %subs = (); $subs{$1}++ while $string =~ m{(([ACGT])\2+)}g; } # v4 sub v5 { %subs = (); $subs{$&}++ while $string =~ m{([ACGT])\1+}g; } # v5 v1 (); is_deeply (\%subs, \%expect, "v1"); v2 (); is_deeply (\%subs, \%expect, "v2"); v3 (); is_deeply (\%subs, \%expect, "v3"); v4 (); is_deeply (\%subs, \%expect, "v4"); v5 (); is_deeply (\%subs, \%expect, "v5"); printf "%5d %3d %s\n", $subs{$_->[1]}, @$_ for sort { $b->[0] <=> $a->[0] || $a->[1] cmp $b->[1] } map {[ length, $_ ]} keys %subs; cmpthese (-2, { v1 => \&v1, v2 => \&v2, v3 => \&v3, v4 => \&v4, v5 => \&v5 }); done_testing;