Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl RE Matching: How can I use a variable for RE flags?

Tags:

regex

perl

In Perl:

my $string = "This is a test";
say "String matches" if $string =~ /this is a test/;          # Doesn't print
say "String sort of matches" if string =~ /this is a test/i;  # Prints

Adding the i flag onto the end of the RE match causes the match to ignore case.

I have a program where I specify the regular expression to match in a separate data file. This works fine. However, I'd like to be able to expand that and be able to specify the regular expression flags to use when checking for a match.

However, in Perl, those RE flags cannot be in a scalar:

my $re_flags = "i";
my $string = "This is a test";
say "This sort of matches" if $string =~ /this is a test/$re_flags;

This results in:

Scalar found where operator expected at ,,, line ,,, near "/this is a test/$re_flags"  
(Missing operator before $re_flags?)
syntax error at ... line ..., near "/this is a test/$re_flags"
Execution of ... aborted due to compilation errors.

Is there a way to use RE flags stored in a scalar variable when evaluating a regular expression?

I know I can use eval:

eval qq(say "This worked!" if \$string =~ /this is a test/$re_flags;);

But I'd like a better way of doing this.

like image 775
David W. Avatar asked Jan 08 '23 09:01

David W.


1 Answers

$ perl -E'say for qr/foo/, qr/foo/i'
(?^u:foo)
(?^ui:foo)

This just goes to show that

/foo/i
s/foo/bar/i

can also be written as

/(?i:foo)/
s/(?i:foo)/bar/

so you could use

/(?$re_flags:foo)/
s/(?$re_flags:foo)/bar/

This will only work for flags that pertain to the regular expression (a, d, i, l, m, p, s, u, x) rather than flags that pertain to the match operator (c, g, o) or the substitution operator (c, e, g, o, r).

like image 82
ikegami Avatar answered Jan 28 '23 02:01

ikegami