Adrian
Adrian

Reputation: 10911

How does perl handle regex with embedded variables?

If I have a set of regexs who are to be defined in an external configuration file and I put them into an array, how does the compilation for those regexs work? Are they referenced somehow so that they are not recompiled every time? So basically, I'd have something like this:

#/usr/bin/perl
# $regexArray simulates what would be read from the config file.
my $regexArray = [
    [ 'foo', 'bar' ]
  , [ '\bboo\b', 'zoo' ]
 #, ... many more pairs here ...
];

while (<>)
{
  for $regexReplace (@$regexArray)
  {
    s/$regexReplace->[0]/$regexReplace->[1]/g
  }
  print;
}

With a @$regexArray being long.

So would it cache these regexs? Or compile them every time? Is there a better way of doing this?

Upvotes: 1

Views: 111

Answers (3)

hwnd
hwnd

Reputation: 70722

For regular expressions stored you can use the qr// operator which takes a regex operand and returns a regex object that can be used of a later match. Regex objects are used mostly to encapsulate a regex that can be used to compile and gain control over when a regex is compiled.

The documentation of Regexp Quote-Like Operators explains mostly everything you're asking.

In the below example, the arg passed to qr// is an already-compiled regular expression:

use re 'debug';

$re1  = qr/baz/;
$re2  = qr/$re1/;

Here, only one regular expression is being compiled..

Compiling REx "baz"
Final program:
   1: EXACT <baz> (3)
   3: END (0)
anchored "baz" at 0 (checking anchored isall) minlen 3 
Freeing REx: "baz"

You could do something like the following which will join your patterns and use the qr// operator.

my $regexArray = [
    ['foo', 'bar'],
    ['\bboo\b', 'zoo'],
];

my $regex = join '|', map $_->[0], @$regexArray;
my $re    = qr/$regex/;

Upvotes: 2

GWP
GWP

Reputation: 131

Your for loop does not use its looping variable and the internals reference stuff that doesn't exist. Please post code that actually runs if you want a meaningful answer.

Upvotes: -1

user4035
user4035

Reputation: 23729

You can use qr function to compile the regexes:

my $regexArray = [
    [ qr/foo/, 'bar' ]
  , [ qr/\bboo\b/, 'zoo' ]
 #, ... many more pairs here ...
];

Then your regexes will be compiled only once, when you define them. Actually, Perl can optimize regexes and, maybe, it won't recompile them anyway.

Upvotes: 4

Related Questions