Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Re: qr// for problem

by BrowserUk (Pope)
on Jun 25, 2011 at 19:26 UTC ( #911392=note: print w/replies, xml ) Need Help??

in reply to qr// for problem

Could you please enlighten me to what am I doing wrong?

When you interpolate the string $number_string into the regex qr/.*$card,$sim.*$number_string.*/ the backslash you originally had on the '+' sign is effectively 'used up'. So by the time the regex comes to be used, that '+' will be treated as a regex meta character, specifically a quantifier modifier, for the preceding space.

Often when interpolating a string into a regex, the way to ensure any meta-like characters within as treated as literals is to bracket the interpolated variable in \Q and \E.

eg. qr/.*$card,$sim.*\Q$number_string\E.*/.

But as the string actually contains meta-characters that you want recognised as such, the other option is to double the backslashes on the '+' so that one remains by the time the regex is used. Ie.

my $number_string = 'Your number is \\+([0-9]+)'; $exp->expect($timeout, [ qr/.*$card,$sim.*$number_string.*/, ...

Which should resolve this particular problem.

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^2: qr// for problem
by silentius (Scribe) on Jun 25, 2011 at 20:08 UTC
    Thank you! This particular problem has a bit of twists... I get the $number_string string from a db and it will most of the times contain meta-like characters that need to taken literally but I also must grab a certain part of the matched line. So I made: my $quoted_number_string = quotemeta $number_string; then I did: $quoted_number_string =~ s/\\\@P\\\@/([0-9]+)/; (where @P@ in the original string marks the place where I must look for a sequence of digits with ([0-9]+)) and these are meta characters that must remain unescaped (so that I can store the matched sequence of digits). Then I finally do: qr/.*$card,$sim.*$quoted_number_string.*/i Now I am in doubt: should aply quotemeta twice like this?
    my $quoted_number_string = quotemeta $number_string; $quoted_number_string = quotemeta $quoted_number_string; $quoted_number_string =~ s/\\\@P\\\@/([0-9]+)/; ... qr/.*$card,$sim.*$quoted_number_string.*/i
    or this will turn each backslash into 3 backslashes instead of just 2? I am confused. Once again thank you!, you have already helped.

      Go step by step. (And, of course, understand each step.)

      AFAIU, the original source string is something like '+fo\o*@P@*b\ar+', in which all metacharacters must be metaquoted, but in which there is a '@P@' sub-string that must also be converted into an actual regex pattern. Studying and experimenting with double- and single-quoting rules will be very helpful.

      >perl -wMstrict -le "my $raw = '+fo\o*@P@*b\ar+'; print qq{'$raw'}; ;; my $mq = quotemeta $raw; print qq{'$mq'}; ;; $mq =~ s{ \\ \@ P \\ \@ }'\+([0-9]+)'xmsg; print qq{'$mq'}; ;; my $mq_rx = qr{$mq}xms; print $mq_rx; ;; my $s = '123 +fo\o*+987*b\ar+ 456'; print qq{'$s'}; $s =~ $mq_rx; print qq{'$1'}; " '+fo\o*@P@*b\ar+' '\+fo\\o\*\@P\@\*b\\ar\+' '\+fo\\o\*\+([0-9]+)\*b\\ar\+' (?msx-i:\+fo\\o\*\+([0-9]+)\*b\\ar\+) '123 +fo\o*+987*b\ar+ 456' '987'

      It's also worth remembering that while the  q{} single-quote operator doesn't interpolate, it does do a bit of escaping WRT the \ backslash character, e.g.:

      >perl -wMstrict -le "my $sq = 'start \ \\ \' stop'; print qq{'$sq'}; " 'start \ \ ' stop'

        Thank you!

        Without your examples I wouldn't even know what functions and operators I had at my disposal to experiment with.

        Thank you so much once again!

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://911392]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (2)
As of 2018-08-15 18:19 GMT
Find Nodes?
    Voting Booth?
    Asked to put a square peg in a round hole, I would:

    Results (162 votes). Check out past polls.