'perl: how to get the original regex from the precompiled version?

Simple code:

use 5.014;
use warnings;

my $re = <DATA>;
chomp $re;
my $re2 = qr/$re/;
say $re2;
__END__
^\w$

result:

(?^u:^\w$)      #added the (?^u:

Is any correct way to decompile $re2 getting back the original regex?

Motivation: the regex is an config value, so need:

  • read it
  • compile it
  • save it to the file for the later use.

But can't save the compiled regex for the later use, because in every compiling the regex got expanded with the (?^u:, so after several cycles i ended with like:

(?^u:(?^u:(?^u:(?^u:(?^u:^\w$)))))

therefore the question are:

  • is here any correct way, how to save the compiled version?
  • if no way - how to decompile, to getting the original version?
  • any idea?


Solution 1:[1]

While I would just keep the string copy around for data usage, and then compile a copy when I needed to use it, you can also use the regexp_pattern function from the core re module to return the pattern used to create a compiled regex:

use re 'regexp_pattern';

print regexp_pattern qr/^\w$/;

prints

^\w$

Solution 2:[2]

re::regexp_pattern

Credits to vpit for pointing this out on MagNET #perl.

Solution 3:[3]

The original is an operator, not a regex pattern. Only looking at the first value returned by regexp_pattern (the pattern) results in information loss. You also need to look at the second (the flags).

qr/foo/                  # pat: foo  flags: u
qr/foo/u                 # pat: foo  flags: u
use re '/u';  qr/foo/    # pat: foo  flags: u

qr/foo/a                 # pat: foo  flags: a
use re '/a';  qr/foo/    # pat: foo  flags: a

qr/foo/i                 # pat: foo  flags: ui
use re '/i';  qr/foo/    # pat: foo  flags: ui
use re '/a';  qr/foo/i   # pat: foo  flags: ai
use re '/ai'; qr/foo/    # pat: foo  flags: ai

To get the closest possible you can get to the original operator, you want

use re qw( regexp_pattern );
my ($pat, $flags) = regexp_pattern($re);
$pat =~ s{/}{\\/}g;
say qq{qr/$pat/$flags};

Solution 4:[4]

Perhaps as simple as:

...
($reoriginal = $re2) =~ s{^\(\?.+:(.+)\)}{$1};
say $reoriginal

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Eric Strom
Solution 2 daxim
Solution 3
Solution 4