
japhy
Enthusiast
/ Moderator
Nov 16, 2000, 12:17 PM
Post #3 of 5
(6554 views)
|
Here is a solution: <BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR> # $REx = any_order("abcdef"); # if ($str =~ $REx) { ... } sub any_order { my $c = shift; my $re; for my $p (0 .. length($c)-1) { $re .= join "", map "(?!\\$_)", 1 .. $p; $re .= "([$c])"; } return qr/$re/; } </pre><HR></BLOCKQUOTE> The important part of this is the line with $re .= join ..., 1 .. $p. This creates a series of negative look-aheads, which basically make a regex like this: <BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR> m{ # match a, b, or c, and store in \1 ([abc]) # make sure \1 won't match # and then match a, b, or c, and store in \2 (?!\1) ([abc]) # make sure \1 and \2 won't match # and then match a, b, or c, and store in \3 (?!\1) (?!\2) ([abc]) }x </pre><HR></BLOCKQUOTE> So in the string "ccba", 'c' is in \1, and then Perl tries to match a, b, or c, but NOT what was matched by \1. So it fails, since 'c' was matched by \1. Then it tries again, starting at the second c, and it works, because \1 matches 'c', \2 matches 'b', and \3 matches 'a'. ------------------ Jeff "japhy" Pinyan -- accomplished author, consultant, hacker, and teacher
|