regexperlvariablesdisambiguation

Perl variable disambiguation within regex


I want to ensure variables are interpolated as they are within perl regular expressions. Would rather avoid binding over to other variables in a cascate of "ifs" that would rarely need that variable throughout the code execution. How could I ensure I used the variable?

use strict;
use warnings FATAL => "all";

$_="botherther";

my $bo = "bother";
if (/^$bother$/) { # want to consider just $bo here!
  print("Undestood regex as /($bo)ther/.\n");
} else {
  print("Couldnt discern variable.\n");
}

my $bi = { bo => "the" };
if (/^bo$bi->{bo}[r]ther$/) { # now, $bi->{bo} only
  print("Discerned /bo($bi->{bo})[r]/\n");
} else {
  print("Couldnt discern variable.\n");
}

I'm not able to find a way to wrap the variables properly within the regex. Of course I could just my $bi_resolved = $bi->{bo} or fill the regex with null-thingies (like [] or ()), but this does not feel like a proper separator.

For clarity:

  1. I wanted to expand $bo into bother to get the /botherther/ string in the first match.
  2. I wanted to expand $bi->{bo} into the to get <bo><the><[r]ther>, again /botherther/ in the second match.
  3. Important noting, I don't care for the sake of this context, about the escapes \Q and \E, "I am assuming there's never metacharacters within the variables".

I have searched thru questions, read documentation, and couldn't find an answer for this. Wrapping in ${} didn't work for me (that's trying to dereference stuff). So, while searching I feel I am just barking at the wrong tree... It's simply unbelievable nobody ever needed to ask something like that around perlmonks or stackoverflow. I'm probably just looking for the wrong keywords here. :/


Solution

  • To separate interpolated variable names from other text is usually
    done like ${name}

    So, a part of the code sample becomes

    use strict;
    use warnings;
    
    $_="botherther";
    
    my $bo = "bother";
    if (/^${bo}ther$/) { # want to consider just $bo here!
      print("Undestood regex as /${bo}ther/.\n");
    } else {
      print("Couldnt discern variable.\n");
    }
    

    A good way to test stuff is to put it into a qr// then print it out :

    my $rx = qr/^${bo}ther$/;
    print $rx;
    

    Per @choroba :

    As far as the regex goes, it looks like the variable can also be wrapped
    in a group without modification and should cover all cases.
    It's really just a parsing thing. If Perl can distinquish delimiters to get
    a variable notation in a string, it will interpolate it.

    Like (?:$bo) or (?:$bi->{bo})
    but it will be wrapped inside a residual group.