in reply to Operator for "these expressions, in any order"

use Algorithm::Permute; my @patterns = (); my $p = new Algorithm::Permute(['X', 'Y', 'Z']); while (@res = $p->next) { push @patterns, join('', @res); } my $pattern = join '|', @patterns; print "$pattern\n"; # give the pattern a test... while (<DATA>) { chomp; print "$_ is ", /^(?:$pattern)$/ ? 'good' : 'bad', "\n"; } __DATA__ XYX XYZ ZYY ZXY ZYX XXYZ

And the output is ...
ZYX|YZX|YXZ|ZXY|XZY|XYZ XYX is bad XYZ is good ZYY is bad ZXY is good ZYX is good XXYZ is bad

Replies are listed 'Best First'.
Re: Operator for "these expressions, in any order"
by Abigail-II (Bishop) on Feb 17, 2004 at 15:58 UTC
    Unfortunally, the size of the resulting regex grows exponentially. There are 6 permutations for 3 choices, 24 for 4, 120 for 5, 720 for 6, and 3628800 for 10.

    Abigail

      Not to be a stickler, but it's not exponential growth. It's worse than that. For instance, 2**4 = 16, but 4! = 24. Choose any base j, and there's a number n such that j**n < n!. Of course, this only strenghens your point...:).

      thor

      Yes I know. That's why I like Randal's solution better. :-)

Re: Re: Operator for "these expressions, in any order"
by jsalvata (Initiate) on Feb 17, 2004 at 23:23 UTC
    I thought I already provided this answer myself.

    However, this does not address the capture-groups issue I mentioned in my question: if X, Y and Z all had capture groups, obtaining their values (and knowing which regexp each comes from) would require some funky code that I need to avoid.

    Let me clarify my problem: the issue is not how to build a matching regexp, but how to keep the capture groups reasonable. The reason for this is that X Y Z would be build from regexps entered by the program users, who would also provide a result pattern, possibly containing $1 $2,... So I need the correspondence between the capture groups in the input regexps and the vars to be easy to describe.