in reply to Re: Dumping regexp for Perl versions earlier than 5.14
in thread Dumping regexp for Perl versions earlier than 5.14

Correction, it's pre/post 5.14 (perl5140delta gives the details).
  • Comment on Re^2: Dumping regexp for Perl versions earlier than 5.14

Replies are listed 'Best First'.
Re^3: Dumping regexp for Perl versions earlier than 5.14
by AnomalousMonk (Archbishop) on Dec 31, 2014 at 17:42 UTC

    I still don't understand your use-case well enough to see why the  "(?adlupimsx-imsx)" embedded pattern-match modifier would not be useful here (see Extended Patterns in perlre).


    Give a man a fish:  <%-(-(-(-<

      OK, let me try again. If I do this on perl 5.14+:
      use 5.010;
      open my($fh), ">", "out";
      my $re = qr/a/;
      say $fh "use 5.010; if ('a' =~ /$re/) { say 'match' } else { say 'no match' }";
      Then out will contain:
      use 5.010; if ('a' =~ /(?^:a)/) { say 'match' } else { say 'no match' }

      This code won't run on perl 5.12 or lower due to unknown regex sequence (?^...), which is introduced in perl 5.14. When run on perl 5.12 or perl 5.10, it will print this error message:

      Sequence (?^...) not recognized in regex; marked by <-- HERE in m/(?^ <-- HERE :a)/ at out line 1.

      I want a code generator that, even though run from perl 5.14+, can generate code that runs on perl 5.12 and lower. So basically I now need to do something like this:

      use 5.010;
      use re qw(regexp_pattern);
      open my($fh), ">", "out";
      my $re = qr/a/;
      my ($pat, $mod) = regexp_pattern($re);
      say $fh "use 5.010; if ('a' =~ /(?$mod-)$pat/) { say 'match' } else { say 'no match' }";
      Note that I left out the part where I need to: 1) remove or complain about regex modifiers that are new in 5.14+ and unrecognized in older perls; 2) escape slashes in pattern. But the main point is there.

      UPDATE: I'm packaging the routine as a CPAN module: Regexp::Stringify

        c:\@Work\Perl>perl -wMstrict -le "print qq{version $]}; ;; my $rx = '(?:(?i)b)'; print qq{match x: '$1'} if 'aaBbBcc' =~ /($rx+)/; ;; my $ry = '(?i-mxs:b)'; print qq{match y: '$1'} if 'aabBbcc' =~ /($ry+)/; " version 5.008009 match x: 'BbB' match y: 'bBb'
        (Same output under version 5.14.4.)

        IOW, instead of storing the stringized representation of a  qr// object, define and store a string that represents a fully backward-compatible regex that can be compiled into a  m// s/// qr// object of any Perl version as needed. Or: why do you need to start with a  qr// that may tied, however loosely, to a particular version? That's the bit I don't grok.


        Give a man a fish:  <%-(-(-(-<

        I want a code generator that, even though run from perl 5.14+, can generate code that runs on perl 5.12 and lower.

        Unless I'm missing a CPAN module capable of stringifying regexes, I'm afraid you won't get that from Perl itself: I believe the relevant commit is fb85c0447bf1, it looks like the stringification behavior is not configurable. The change was discussed, including compatibility, on P5P, e.g. here.

        If you really don't like the two suggestions from perl5140delta, then you might actually want to consider using an older Perl to generate your regex strings.