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

Hello Monks, why are the two results different?
$x = "A\\B";
$y = "Here is A\\B";
print $y =~ /$x/ ? "y" : "n";

$x = "\\B";
$y = "Here is \\B";
print $y =~ /$x/ ? "y" : "n";
Prints: ny although only the 'A' is different. What is so special about the backslash, that it knows about what is in front.
Yours
Stefan (no monk whatsoever)

Replies are listed 'Best First'.
Re: Strange backslash in regexp behaviour
by ikegami (Patriarch) on Aug 20, 2009 at 14:31 UTC

    The \\B in the string literal becomes \B in the resulting string.

    In a regex pattern, \B means "Match except at a word boundary".

    Since the \B is between an "A" and the end of the string in the first snippet, it's on a word boundary.

    Since the \B is between a space and the end of the string in the second snippet, it's not on a word boundary.

    You want

    $pat = "A\\\\B"; $text = /$pat/
    or
    $pat = qr/A\\B/; $text = /$pat/
    or
    $substr = "A\\B"; $text = /\Q$substr\E/
Re: Strange backslash in regexp behaviour
by SuicideJunkie (Vicar) on Aug 20, 2009 at 14:27 UTC
Re: Strange backslash in regexp behaviour
by JavaFan (Canon) on Aug 20, 2009 at 14:29 UTC
    "\\B" is a backslash followed by a B. The regexp engine considers that an zero-width check (not a word/non-word boundary). But A isn't followed by a letter.

    Use $x = qr/A\\B/ instead.

Re: Strange backslash in regexp behaviour
by Anonymous Monk on Aug 21, 2009 at 03:35 UTC
    use YAPE::Regex::Explain; print YAPE::Regex::Explain->new("A\\B")->explain; __END__ The regular expression: (?-imsx:A\B) matches as follows: NODE EXPLANATION ---------------------------------------------------------------------- (?-imsx: group, but do not capture (case-sensitive) (with ^ and $ matching normally) (with . not matching \n) (matching whitespace and # normally): ---------------------------------------------------------------------- A 'A' ---------------------------------------------------------------------- \B the boundary between two word chars (\w) or two non-word chars (\W) ---------------------------------------------------------------------- ) end of grouping ----------------------------------------------------------------------
    use YAPE::Regex::Explain; print YAPE::Regex::Explain->new("\\B")->explain; __END__ The regular expression: (?-imsx:\B) matches as follows: NODE EXPLANATION ---------------------------------------------------------------------- (?-imsx: group, but do not capture (case-sensitive) (with ^ and $ matching normally) (with . not matching \n) (matching whitespace and # normally): ---------------------------------------------------------------------- \B the boundary between two word chars (\w) or two non-word chars (\W) ---------------------------------------------------------------------- ) end of grouping ----------------------------------------------------------------------
    use re 'debug'; $x = "A\\B"; $y = "Here is A\\B"; print $y =~ /$x/ ? "y" : "n"; __END__ Compiling REx `A\B' size 4 Got 36 bytes for offset annotations. first at 1 1: EXACT <A>(3) 3: NBOUND(4) 4: END(0) anchored "A" at 0 (checking anchored) minlen 1 Offsets: [4] 1[1] 0[0] 2[2] 4[0] Guessing start of match, REx "A\B" against "Here is A\B"... Found anchored substr "A" at offset 8... Starting position does not contradict /^/m... Guessed: match at offset 8 Matching REx "A\B" against "A\B" Setting an EVAL scope, savestack=3 8 <Here is > <A\B> | 1: EXACT <A> 9 <Here is A> <\B> | 3: NBOUND failed... Match failed nFreeing REx: `"A\\B"'
    use re 'debug'; $x = "\\B"; $y = "Here is \\B"; print $y =~ /$x/ ? "y" : "n"; __END__ Compiling REx `\B' size 2 Got 20 bytes for offset annotations. first at 1 1: NBOUND(2) 2: END(0) stclass "NBOUND" minlen 0 Offsets: [2] 1[2] 3[0] Matching REx "\B" against "Here is \B" Matching stclass "NBOUND" against "Here is \B" Setting an EVAL scope, savestack=3 1 <H> <ere is \B> | 1: NBOUND 1 <H> <ere is \B> | 2: END Match successful! yFreeing REx: `"\\B"'