http://www.perlmonks.org?node_id=531680


in reply to Testing regex equivalence

I'm not sure what exactly your goal is. Every regular expression of a certain size either has no loops or it has loops, and if it has loops, there is a certain string length after which parts of the regular expression repeat (I believe this is more or less the pumping lemma). So to find out whether two regular expressions are equal, you need to check all strings below the maximum of the two respectice string lengths.

But this idea only works for "real" regular expressions (in the computer science meaning), not for Perl Regular Expressions in general. So it will help to know if your regular expressions are regular or not.

If they are regular in the CS sense, you can parse the regular expression and then convert it into a finite state machine. Then you "just" need to create all strings of length smaller or equal to twice the number of states, and check for those strings if they either match both or fail both regular expressions.

Replies are listed 'Best First'.
Re^2: Testing regex equivalence
by loris (Hermit) on Feb 21, 2006 at 13:13 UTC

    What I want to do is really to parse the regex in some way and simplifiy it, if possible. So say I have a regex generator and for a certain input it produces

    .*(.*)$

    I would like to be able to recognise that this is the same as

    .*

    Thanks,

    loris


    "It took Loris ten minutes to eat a satsuma . . . twenty minutes to get from one end of his branch to the other . . . and an hour to scratch his bottom. But Slow Loris didn't care. He had a secret . . ."

      They aren't strictly equivalent, because the first regex has capturing parentheses even if they only will ever match the empty string at the end of the string. But assuming you have

      /(?:.*).*$/ # and /.*$/

      you could convert them into canonical form, that is, normalize all .* to become (?:.*), and then simplify, mapping (?:.*)(?:.*) to (?:.*).