3
$\begingroup$

Preface: This will turn out to be a bad case of brain-malfunction. In any case, the precedence is surprising and I haven't checked the FullForm... the one thing we tell every new user. Oh my


This question is for reference. I believe this is a bug. Assume you want to match 3 cases: 123, .123, and (123. or 123.123). The documentation of StringExpression states:

img

Let's try both versions we can use:

n1 = {DigitCharacter .., "." ~~ DigitCharacter .., 
      DigitCharacter .. ~~ "." ~~ DigitCharacter ...};

n2 = DigitCharacter .. | "." ~~ DigitCharacter .. |
     DigitCharacter .. ~~ "." ~~ DigitCharacter ...;

Now you will note that the created regular expressions look differently

First[StringPattern`PatternConvert[#]] & /@ {n1, n2}
{
 "(?ms)(?:\\d+|\\.\\d+|\\d+\\.\\d*)", 
 "(?ms)(?:\\d+|\\.)(?:\\d+|\\d+)\\.\\d*"
} 

and in fact, they have different semantics

StringMatchQ[".1", #] & /@ {n1, n2}
(* {True, False} *)

Any suggestions, why this shouldn't be a bug?

$\endgroup$
  • $\begingroup$ How did you find StringPattern`PatternConvert? $\endgroup$ – Mike Honeychurch Jan 24 '18 at 4:23
  • 1
    $\begingroup$ @MikeHoneychurch A bad case of Trace that I used to solve a users problem some years ago. It is quite handy at times. $\endgroup$ – halirutan Jan 24 '18 at 4:34
3
$\begingroup$

Look at the FullForm of n2:

n2 = DigitCharacter .. | "." ~~ DigitCharacter .. | DigitCharacter .. ~~ "." ~~ DigitCharacter ...;
n2 //FullForm

StringExpression[Alternatives[Repeated[DigitCharacter],"."],Alternatives[Repeated[DigitCharacter],Repeated[DigitCharacter]],".",RepeatedNull[DigitCharacter]]

Note that the head is not Alternatives. The issue is the precedence of | vs ~~. The following version works:

n2 = Alternatives[
    DigitCharacter ..,
    "." ~~ DigitCharacter ..,
    DigitCharacter .. ~~ "." ~~ DigitCharacter ...
];
StringMatchQ[".1", n2]

True

| improve this answer | |
$\endgroup$
  • $\begingroup$ Nice! Indeed, I looked at the full-form but it's already 5:25 in the morning and I must have missed this obviously. I just assumed that Alternatives is Flat. Oh my.. Thanks. $\endgroup$ – halirutan Jan 24 '18 at 4:25
  • $\begingroup$ In any case, this is a bad trap and makes the documentation that says or very questionable. Who uses an even mildly interesting regex without the ~~ operator? $\endgroup$ – halirutan Jan 24 '18 at 4:28
  • $\begingroup$ Forget the Flat comment. It's far too late. $\endgroup$ – halirutan Jan 24 '18 at 4:33

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.