Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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 *)
share|improve this question
    
You are binding the first x_ with the first alternative. Try {StringMatchQ["ab", (x_ ~~ "c") | ("a" ~~ y_)], StringMatchQ["ab", ("a" ~~ x_) | (y_ ~~ "c")]} instead –  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 –  belisarius Sep 17 '13 at 18:22
2  
You may see that x_ becomes bounded to an empty string FullForm@StringReplace["ab", Alternatives[(x_ ~~ "c"), ("a" ~~ y_)] :> 2 x] –  belisarius Sep 17 '13 at 19:22
5  
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

1 Answer 1

up vote 6 down vote accepted

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>.))

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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