in reply to How to replace greedy alternation?

I'll offer yet another solution....
There is a requirement that each of the letters much appear at least once. And I interpret "order" to mean the order that they appeared in the string, not in frequency or order of the list that we are looking for...maybe that is wrong.

The match global will just go through the input string once. The while() loop iterates over a list that the match global expression produced. I'm not sure how "smart" regex is with /o option (compile regex once). Having a join may be slower than I think, but my testing so far with Perl 5.10 says that regex is way smarter (and faster) than it used to be! You can do the join other ways or declare other variables. One main point about regex is that picking from a set [xyz] is a lot faster than /x/|/y/|/z|.

Map and sort are pretty "heavy weight" critters. A hash table especially with a small number of keys is very efficient. A Perl hash gets created by default with 8 hash "buckets". Don't be afraid to use a hash. This code is verbose, but is straightforward and will run quickly.

#!/usr/bin/perl -w use strict; my $str = "1b22a3d3cab"; my @letters = qw (a b 2 c d); my @order_found =(); my %seen =(); #UPDATE: don't need the $found variable, oops! #while (my $found = $str =~ m/([join("",@letters)])/go) #should have been: while ($str =~ m/([join("",@letters)])/go) { push (@order_found, $1) unless $seen{$1}; $seen{$1}++; } if (keys %seen != @letters) { print "not all letters found\n"; } else { print @order_found, "\n"; # prints b2adc }