Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a modifier to a quoted regular (qr) expression

Is there an easy way to add regex modifiers such as 'i' to a quoted regular expression? For example:

$pat = qr/F(o+)B(a+)r/;
$newpat = $pat . 'i'; # This doesn't work

The only way I can think of is to print "$pat\n" and get back (?-xism:F(o+)B(a+)r) and try to remove the 'i' in ?-xism: with a substitution

like image 373
dividebyzero Avatar asked Nov 10 '11 16:11

dividebyzero


People also ask

What is * in Perl regex?

Regular Expression (Regex or Regexp or RE) in Perl is a special text string for describing a search pattern within a given text. Regex in Perl is linked to the host language and is not the same as in PHP, Python, etc. Sometimes it is termed as “Perl 5 Compatible Regular Expressions“.

What does !~ Mean in Perl?

!~ is the negation of the binding operator =~ , like != is the negation of the operator == . The expression $foo !~ /bar/ is equivalent, but more concise, and sometimes more expressive, than the expression !($foo =~ /bar/)

What is K in regex?

\K resets the starting point of the reported match. Any previously consumed characters are no longer included in the final match. To make the explanation short, consider the following simple Regex: a\Kb. When "b" is matched, \K tells the Regex engine to pretend that the match attempt started at this position.

How do I match parentheses in Perl?

Whenever you use parentheses for grouping, they automatically work as memory parentheses as well. So, if you use /./, you'll match any single character (except newline); if you use /(.)/, you'll still match any single character, but now it will be kept in a regular expression memory.


3 Answers

You cannot put the flag inside the result of qr that you already have, because it’s protected. Instead, use this:

$pat = qr/F(o+)B(a+)r/i;
like image 167
tchrist Avatar answered Sep 22 '22 11:09

tchrist


You can modify an existing regex as if it was a string as long as you recompile it afterwards

  my $pat = qr/F(o+)B(a+)r/;
  print $pat, "\n";
  print 'FOOBAR' =~ $pat ? "match\n" : "mismatch\n";

  $pat =~ s/i//;
  $pat = qr/(?i)$pat/;
  print $pat, "\n";
  print 'FOOBAR' =~ $pat ? "match\n" : "mismatch\n";

OUTPUT

  (?-xism:F(o+)B(a+)r)
  mismatch
  (?-xism:(?i)(?-xsm:F(o+)B(a+)r))
  match
like image 30
Borodin Avatar answered Sep 18 '22 11:09

Borodin


Looks like the only way is to stringify the RE, replace (-i) with (i-) and re-quote it back:

my $pat = qr/F(o+)B(a+)r/;
my $str = "$pat";
$str =~ s/(?<!\\)(\(\?\w*)-([^i:]*)i([^i:]*):/$1i-$2$3:/g;
$pati = qr/$str/; 

UPDATE: perl 5.14 quotes regexps in a different way, so my sample should probably look like

my $pat = qr/F(o+)B(a+)r/;
my $str = "$pat";
$str =~ s/(?<!\\)\(\?\^/(?^i/g;
$pati = qr/$str/;

But I don't have perl 5.14 at hand and can't test it.

UPD2: I also failed to check for escaped opening parenthesis.

like image 38
Dallaylaen Avatar answered Sep 18 '22 11:09

Dallaylaen