# Named string patterns in Alternatives, why does it depend on order?

When using the same name for part of patterns inside Alternatives how come it behaves differently for strings than in normal patterns?

{StringMatchQ["ab", (x_ ~~ "c") | ("a" ~~ x_)],
StringMatchQ["ab", ("a" ~~ x_) | (x_ ~~ "c")]}
(* False, True *)

{MatchQ[{1, 2}, {x_, 3} | {1, x_}],
MatchQ[{1, 2}, {1, x_} | {x_, 3}]}
(* True, True *)

StringMatchQ["ab", (x_ ~~ "c") | (x_ ~~ "b")]
(* False *)

• You are binding the first x_ with the first alternative. Try {StringMatchQ["ab", (x_ ~~ "c") | ("a" ~~ y_)], StringMatchQ["ab", ("a" ~~ x_) | (y_ ~~ "c")]} instead – Dr. belisarius Sep 17 '13 at 18:04
• @belisarius I don't think it's that simple, look for instance at: StringMatchQ["ab", (x_ ~~ "c") | (x_ ~~ "b")] if x was bound to "a" then it would still match on the second one – ssch Sep 17 '13 at 18:19
• perhaps x is bound to Undefined in the first try. Just ranting. Of course if you replace the secon x_ by y_, it works again – Dr. belisarius Sep 17 '13 at 18:22
• You may see that x_ becomes bounded to an empty string FullForm@StringReplace["ab", Alternatives[(x_ ~~ "c"), ("a" ~~ y_)] :> 2 x] – Dr. belisarius Sep 17 '13 at 19:22
• String patterns are fundamentally different from ordinary patterns, as they are actually converted into regular expressions and passed off to the PCRE library for processing. As such, their features, limitations, and behaviors are exactly those of PCREs. Why this particular behavior arises I don't personally know, but if you look into the PCRE documentation you might find an answer. – Oleksandr R. Sep 17 '13 at 19:42

The tutorial,in the Implementation Details section, mentions PatternConvert that shows the translation used:
StringPatternPatternConvert[(x_ ~~ "c") | ("a" ~~ x_)]

The relevant part here is (?:(.)c|a(?:\1)) when I was expecting something like: (?:(?<x>.)c|a(?<x>.))`