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

Hi all. I think I'm missing something simple but I just can't see it.

I am trying to split a string on markers that I don't want to hard-code. My patterns aren't behaving - here's a simple stub of what is throwing me.

use strict; my $patt1 = '!!'; my $patt2 = '++'; my $string = 'hello!!there++everyone!!in the web'; if ( $string =~ m{$patt1} ) { print "Matches patt1\n"; } if ( $string =~ m{\Q $patt2 \E}x ) { print "Matches patt2 with /x\n"; } if ( $string =~ m{\Q$patt2\E} ) { print "Matches patt2\n"; }

I would have thought this would have matched all 3 times but the /x modifier doesn't match it. Does the \Q\E make the spaces significant?

Can someone see why?

Thanks!

Replies are listed 'Best First'.
Re: /x modifier with \Q and \E
by NetWallah (Canon) on Apr 01, 2008 at 05:37 UTC
    From perlre:
    Also note that anything inside a \Q...\E stays unaffected by /x.
    In other words, whitespace IS significant inside quotemeta, regardless of /x.

         "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

      aaaaaahhh! Thanks

      My version of perldoc doesn't have that sentence! I just checked online and the sentence is there. Must have been updated since my Perl.

      Thanks again.

      (I missed OP's reply which stated the same as below.)

      I could not find that line in my copies of perlre or perlop (perl 5.8.7) ...

      { perldoc perlre ; perldoc perlop ; } | grep -C 2 unaffected just as in ordinary Perl code. This also means that if you wan +t real whitespace or "#" characters in the pattern (outside a characte +r class, where they are unaffected by "/x"), that you'll either have to +escape them or encode them using octal or hex escapes. Taken together +, these features go a long way towards making Perl's regular expression +s more -- cards, pipes, and redirections will be honored. The co +llected standard output of the command is returned; standard er +ror is unaffected. In scalar context, it comes back as a sing +le (potentially multi-line) string, or undef if the comman +d failed. In list context, returns a list of lines (howe +ver
Re: /x modifier with \Q and \E
by parv (Parson) on Apr 01, 2008 at 05:27 UTC

    /x apparently has no effect. \Q is what affects the space (for \Q implies to quote any characters following it, till the end or upto \E if present).

    # Need perl to be built with DEBUGGING perl -Dr -e '$p = qr{\Q ++ \E} ; $q = qr{\Q ++ \E}x ; $r = qr{\Q++\E}' Compiling REx `\ \+\+\ ' size 3 Got 28 bytes for offset annotations. first at 1 rarest char + at 1 1: EXACT < ++ >(3) 3: END(0) anchored " ++ " at 0 (checking anchored isall) minlen 4 Offsets: [3] 1[8] 0[0] 9[0] Compiling REx `\ \+\+\ ' size 3 Got 28 bytes for offset annotations. first at 1 rarest char + at 1 1: EXACT < ++ >(3) 3: END(0) anchored " ++ " at 0 (checking anchored isall) minlen 4 Offsets: [3] 1[8] 0[0] 9[0] Compiling REx `\+\+' size 3 Got 28 bytes for offset annotations. first at 1 rarest char + at 0 1: EXACT <++>(3) 3: END(0) anchored "++" at 0 (checking anchored isall) minlen 2 Offsets: [3] 1[4] 0[0] 5[0] Omitting $` $& $' support. EXECUTING... Freeing REx: `"\\ \\+\\+\\ "' Freeing REx: `"\\ \\+\\+\\ "' Freeing REx: `"\\+\\+"'

    I consulted perlre to see if there was anything about a space with \Q & /x. Finding nothing there, I moved to the pointer provided to Gory details of parsing quoted constructs in perlop. That section also did not list anything about the topic. The reading of that section, however, was interesting. All was not in vain.

      Thanks parv - I thought I'd try the regex debugger too just before I posted the message. I saw that it was trying to anchor ' ++ ', which prompted my question at the end of the original post. It surprised me and I thought I'd lost the plot somewhere along the line.

      I wanted to make it possible for my script to handle special regex characters (like the +) so at this point, I think I'll just write cluttered regex's unless someone can point out how to do it :-)

      Thanks

        I suppose you are aware of quotemeta function, which you could use for the same effect of \Qpattern\E something like (one of many variations) ...

        my @patterns = map { quotemeta $_ } @string

        In any case, as the Gory details says, be aware of what happens with [$@] in \Q (or quotemeta) including other meta characters.