Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use a variable as a regex modifier in Perl?

I'm writing an abstraction function that will ask the user a given question and validate the answer based on a given regular expression. The question is repeated until the answer matches the validation regexp.

However, I also want the client to be able to specify whether the answer must match case-sensitively or not.

So something like this:

sub ask {
    my ($prompt, $validationRe, $caseSensitive) = @_;
    my $modifier = ($caseSensitive) ? "" : "i";
    my $ans;
    my $isValid;

    do {
        print $prompt;
        $ans = <>;
        chomp($ans);

        # What I want to do that doesn't work:
        # $isValid = $ans =~ /$validationRe/$modifier;

        # What I have to do:
        $isValid = ($caseSensitive) ?
            ($ans =~ /$validationRe/) :
            ($ans =~ /$validationRe/i);

    } while (!$isValid);

    return $ans;
}

Upshot: is there a way to dynamically specify a regular expression's modifiers?

like image 424
livefree75 Avatar asked Dec 20 '14 02:12

livefree75


2 Answers

Upshot: is there a way to dynamically specify a regular expression's modifiers?

From perldoc perlre:

"(?adlupimsx-imsx)" "(?^alupimsx)" One or more embedded pattern-match modifiers, to be turned on (or turned off, if preceded by "-") for the remainder of the pattern or the remainder of the enclosing pattern group (if any).

This is particularly useful for dynamic patterns, such as those read in from a configuration file, taken from an argument, or specified in a table somewhere. Consider the case where some patterns want to be case-sensitive and some do not: The case-insensitive ones merely need to include "(?i)" at the front of the pattern.

Which gives you something along the lines of

$isValid = $ans =~ m/(?$modifier)$validationRe/;

Just be sure to take the appropriate security precautions when accepting user input in this way.

like image 179
Slade Avatar answered Oct 04 '22 21:10

Slade


You might also like the qr operator which quotes its STRING as a regular expression.

my $rex = qr/(?$mod)$pattern/;
$isValid = <STDIN> =~ $rex;
like image 27
Pavel Avatar answered Oct 04 '22 19:10

Pavel