2
$\begingroup$

I try to construct patterns using Riffle and Except

StringExpression@Riffle[{"a", "b", "c"}, Except[{"=", ","}] ..]

and expect it to match "a_b_c", but not "a_bc" because Except is repeated .. one or more times.

However,

StringMatchQ["a_bc", StringExpression@Riffle[{"a", "b", "c"}, Except[{"=", ","}] ..]]

returns True. Could anyone explain why is it so?

$\endgroup$
3
  • $\begingroup$ Well, I don't know, but I think this has something to do with how the pattern is translated into a Perl-compatible regular expression and then understood by the PCRE library. The regex is given by First@StringPattern`PatternConvert@Riffle[{"a", "b", "c"}, Except[{"=", ","}] ..] and comes out as (?ms)(?:a|(?:[^=,])+|b|(?:[^=,])+|c). Perhaps someone with more experience of using regular expressions will be able to suggest why this behaves as it does. $\endgroup$ May 11, 2014 at 4:01
  • $\begingroup$ StringExpression@@... $\endgroup$
    – ciao
    May 11, 2014 at 4:30
  • $\begingroup$ @rasher, thank you for the answer. OleksandrR., thank you for your help. $\endgroup$ May 11, 2014 at 5:01

1 Answer 1

7
$\begingroup$

You're invoking when you should be applying:

StringExpression@Riffle[{"a", "b", "c"}, Except[{"=", ","}] ..]

(* StringExpression[{"a", Except[{"=", ","}] .., "b",  Except[{"=", ","}] .., "c"}] *)

VS

StringExpression @@ Riffle[{"a", "b", "c"}, Except[{"=", ","}] ..]

(* "a" ~~ Except[{"=", ","}] .. ~~ "b" ~~ Except[{"=", ","}] .. ~~ "c" *)

Note that the first way ends up equivalent to

StringMatchQ[...,{"a", Except[{"=", ","}] .., "b", Except[{"=", ","}] .., "c"}]

which of course gives you unwanted matches (recall that the list is treated as alternatives).

Using application, the correct

StringMatchQ[...,"a" ~~ Except[{"=", ","}] .. ~~ "b" ~~ Except[{"=", ","}] .. ~~ "c"]

is generated, giving the desired results.

$\endgroup$
2
  • $\begingroup$ (+1) Didn't know that StringMatchQ accepts list as a second argument. Is it documented anywhere? $\endgroup$ May 22, 2016 at 20:21
  • 1
    $\begingroup$ @AlexeyPopkov: It must be... but I'll be damned if I can find it. I've been using that form for ages... StringCases has that form documented, perhaps one of those "...I wonder if this works here...", it did, and I've used it since. $\endgroup$
    – ciao
    May 22, 2016 at 20:55

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.