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

Hey guys,
I was hacking around and reading the transcript for japhy's regex book, and I found some weird behavior.

It started when I found out that you could use whitespace after the m, so long as the whitespace was followed by a word character.

$str =~ m TpatternTi;
Yes its ugly, and probably a bad idea but I thought it might make for a funky piece to an obfu. So I started playing around:
# the only obfu'd part of this code would be the regex # which fails anyway so nevermind the obfu # more concerned with the behavior $str = "foobar fOObar"; $x = qr/(foo)/i; print $1 while ($str =~ m _${x}_g); print "\n"; # prints 'foofOO\n' to STDOUT - fine $str = "foobar fOObar"; $x = "(foo)"; print $1 while ($str =~ m _${x}_g); print "\n"; # prints 'foo\n' to STDOUT - also fine # this is where it gets weird # and of course the part I most badly wanted to work $str = "foobar fOObar"; $_ = qr/(foo)/i; print $1 while ($str =~ m _${_}_g); print "\n"; # throws error: # Missing right bracket at az.pl line 17, within pattern
Okay, line 17 is the last line of the script and everything else is commented out so I'm 99.9% sure its no glitch in my code. And the bracket is definitely there so what gives?

At first I thought that maybe there was no interpolation performed if you used the whitespace+word character delimiter, but it works fine with $x

Any ideas?

BTW, it doesn't look particularly confusing after all, but I'd still like to know what's happening here ;0).




Amel

Replies are listed 'Best First'.
Re: Error with Regex Interpolation
by japhy (Canon) on Apr 22, 2002 at 21:04 UTC
    The _ in ${_} is being seen as the closing regex delimiter. Use ${\_} instead.

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a (from-home) job
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re: Error with Regex Interpolation
by Chmrr (Vicar) on Apr 22, 2002 at 21:12 UTC

    You're confusing the heck out of the tokenizer -- it gets to the _ in ${_} and thinks that you want to terminate the regex. Use a \ to get perl to understand what you mean. An example:

    $_ = "o"; print "foo\n" if "foo" =~ m _${_}_; # Dies print "foo\n" if "foo" =~ s _${\_}_; # Happy

    perl -pe '"I lo*`+$^X$\"$]!$/"=~m%(.*)%s;$_=$1;y^`+*^e v^#$&V"+@( NO CARRIER'