Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Do I need to do escaping in my regex check?

by stevieb (Canon)
on Mar 14, 2022 at 14:14 UTC ( [id://11142083]=perlquestion: print w/replies, xml ) Need Help??

stevieb has asked for the wisdom of the Perl Monks concerning the following question:

Good day my fellow esteemed Monks!

I come to you today with what I think is an easy one... I'm doing a validation check on input data, but I'm not getting expected results. Down deep in my software I've got the following sub, which compares a value against a list of enum type values. The important part for this discussion is the regex check:

sub enum { my ($attr, $value, $constraints) = @_; my $enum_values = $constraints->{enum}; if (scalar @$enum_values) { if (! (grep /^$value$/, @$enum_values)) { my $enum_values_string = join ', ', @$enum_values; return "Attribute $attr is enum type but value '$value' is +n't one of '$enum_values_string'"; } } return 0; }

Here's the test failure, which shows the actual value I'm trying to send in, along with the actual allowed values. You can see by eye that there's a match (the "isn't one of" is a joined string of the allowed values, separated by comma):

Attribute PoweredBy is enum type but value 'None (Private Label)' isn't one of 'None (Private Label), Text, Banner, Extra' at tests/Email/035_email_model_broadcast.t line 199.

Is this a failure due to the parens not being escaped? What's the best way to handle this? I'd rather not have to escape the input data, and I can't manually escape the allowed values in the sub above as the data is pulled from a database.

Thanks,

-stevieb

Replies are listed 'Best First'.
Re: Do I need to do escaping in my regex check?
by choroba (Cardinal) on Mar 14, 2022 at 14:34 UTC
    If you are checking one of the values is present, you don't need a regex at all.
    if (! grep $_ eq $value, @$enum_values) {

    If you want to match regexes, you need to store regexes, not strings. Use quotemeta to escape the strings.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: Do I need to do escaping in my regex check?
by hv (Prior) on Mar 14, 2022 at 14:39 UTC

    Yes, the parens are being treated as regexp metacharacters. You can escape it outside the pattern using quotemeta($value), or within the pattern using \Q...\E:

    if (! (grep /^\Q$value\E$/, @$enum_values)) {

    However I'd normally rather do this as a hash lookup - faster, and it's already an equality check:

    my %enum_values = map +($_ => 1), @{ $constraints->{enum} }; if (keys(%enum_values) && !$enum_values{$value}) { my $enum_values_string = join ', ', sort keys %enum_values; ...

    Another option is using the List::Util function 'none' (or 'any' for the inverse):

    use List::Util qw{ none }; if (none { $_ eq $value } @$enum_values) { ...
Re: Do I need to do escaping in my regex check?
by LanX (Saint) on Mar 14, 2022 at 14:43 UTC
    > grep /^$value$/,

    Seems like you want grep /^\Q$value$/, ... (see quotemeta ), but I agree with brother choroba that you are overcomplicating things.

    • If you want a literal string to be anchored at start ^ and end $ , using eq is the straightforward solution.³
    • If you want the literal value to match partially, using grep /\Q$value/, ... without both anchors makes sense.²
    • If you want $value to contain some regex syntax, you have to escape the unintended metas individually°

    updates

    °) like "None \\(Private Label\\)" , please note the need for double escaping aka slasheritis

    ²) added missing \Q

    ³) see also 99 Perl Problems ;-)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11142083]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (6)
As of 2024-04-19 08:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found