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 *)
  • $\begingroup$ You are binding the first x_ with the first alternative. Try {StringMatchQ["ab", (x_ ~~ "c") | ("a" ~~ y_)], StringMatchQ["ab", ("a" ~~ x_) | (y_ ~~ "c")]} instead $\endgroup$ Sep 17, 2013 at 18:04
  • $\begingroup$ @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 $\endgroup$
    – ssch
    Sep 17, 2013 at 18:19
  • $\begingroup$ 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 $\endgroup$ Sep 17, 2013 at 18:22
  • 2
    $\begingroup$ You may see that x_ becomes bounded to an empty string FullForm@StringReplace["ab", Alternatives[(x_ ~~ "c"), ("a" ~~ y_)] :> 2 x] $\endgroup$ Sep 17, 2013 at 19:22
  • 6
    $\begingroup$ 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. $\endgroup$ Sep 17, 2013 at 19:42

1 Answer 1


As @OleksandrR pointed out string patterns are translated to PCRE

The tutorial,in the Implementation Details section, mentions PatternConvert that shows the translation used:

StringPattern`PatternConvert[(x_ ~~ "c") | ("a" ~~ x_)]
(* {"(?ms)(?:(.)c|a(?:\\1))", {{Hold[x], 1}}, {}, Hold[None]} *)

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


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.