6

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

skaffman
  • 398,947
  • 96
  • 818
  • 769
dividebyzero
  • 1,243
  • 2
  • 9
  • 17

3 Answers3

6

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;
tchrist
  • 78,834
  • 30
  • 123
  • 180
2

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
Borodin
  • 126,100
  • 9
  • 70
  • 144
  • 1
    +1 for showing the appropriate way to plant a modifier into an existing regex. The `(?…)` part is documented in http://perldoc.perl.org/perlre.html#Extended-Patterns – daxim Nov 14 '11 at 10:59
  • 3
    This doesn't work after Perl 5.12 because the regex stringification changed. – brian d foy Nov 26 '11 at 06:39
1

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.

Dallaylaen
  • 5,268
  • 20
  • 34