Suppose that I have the following sample list, called list
:
list = {"bBb", "aAa", "aaa"};
Now suppose I want to select the elements that do not contain the string "A"
. One way to do this is to use Select
with StringMatchQ
:
Select[list, ! StringMatchQ[#, ___ ~~ "A" ~~ ___] &]
{"bBb", "aaa"}
(See, for example, this old question.)
But, instead of selecting the elements which do not contain "A"
, is it possible to use Select
with StringMatchQ
, but this time selecting all patterns except those that match the pattern ___ ~~ "A" ~~ ___
. My thought is to use Except
:
Select[list, StringMatchQ[#, Except[___ ~~ "A" ~~ ___]] &]
{}
StringExpression::invld: Element
Except[___ ~~ "A" ~~ ___]
is not a valid string or pattern element inStringExpression[Except[___ ~~ "A" ~~ ___]]
But I get the error message above. So I looked in the documentation for StringMatchQ
. It has the following three general syntax forms:
StringMatchQ["string", patt]
StringMatchQ["string", RegularExpression["regex"]]
StringMatchQ[{s1, s2, ...}, p]
Thinking about the first form, StringMatchQ
takes a pattern as its second argument. I know that ___ ~~ "A" ~~ ___
is a pattern, but is Except[___ ~~ "A" ~~ ___]
a pattern? According to the documentation for Except
, it is. The next question is, is Except[___ ~~ "A" ~~ ___]
a string pattern? According to the error message above, it would seem not. (Also, apparently StringMatchQ
takes only string patterns as its second argument -- which, of course, is logical.)
So, my overall question is, why does Select[list, StringMatchQ[#, Except[___ ~~ "A" ~~ ___]] &]
give an error?
Except
is generally buggy with strings, which is why I always avoid it (with strings). For instance, compare:StringMatchQ["a", Except["b"]]
andStringMatchQ["a", Except["bb"]]
$\endgroup$StringExpression
doc says:Except[p] - any character except ones matching p
IMHO implying that p can only be a character in this context and not a string. Behavior is therefore documented and not a bug. $\endgroup$StringMatchQ
internally callsStringExpression
on the second argument. That also explains OP's error then. You should post that as an answer. $\endgroup$