What would be the best way to detect if a pattern corresponds to a string pattern ?
An invalid string pattern p
would lead to an error in StringMatchQ[string, p]
for example.
4 Answers
At Faysal's behest: there's the (undocumented) function System`Dump`validStringExpressionQ[]
:
System`Dump`validStringExpressionQ["**"]
True
System`Dump`validStringExpressionQ[_ ~~ 1]
False
-
$\begingroup$ A look at
??System`Dump`validStringExpressionQ
is particularly enlightening... $\endgroup$ Commented Nov 20, 2012 at 10:01 -
$\begingroup$ Indeed so basically the pattern is passed to StringMatchQ in the general case and the function checks that no error occured. $\endgroup$– faysouCommented Nov 20, 2012 at 10:31
-
5$\begingroup$ +1. A look at the implementation reveals some unpleasant behavior,e.g.
stpatt = "**"; System`Dump`validStringExpressionQ[stpatt]
returnsFalse
, whileSystem`Dump`validStringExpressionQ[Evaluate[stpatt]]
returnsTrue
. I would prefer to getTrue
in both cases. $\endgroup$ Commented Nov 20, 2012 at 10:33
StringPatternQ[_String | _StringExpression | _RegularExpression] = True;
StringPatternQ[_] = False;
There is the internal GeneralUtilities`StringPatternQ
:
? GeneralUtilities`StringPatternQ
StringPatternQ[expr] gives True if expr is a valid string pattern,
suitable for use with e.g. StringMatchQ
It is a predicate that allows for the most inclusive match, thus it returns True
for any pattern that could stand for a string pattern.
GeneralUtilities`StringPatternQ[_] (* ==> True *)
However, it is less precise as System`Dump`validStringExpressionQ
:
patt = {"s", "*", "**", __, Except@_, x, _ ~~ 1};
GeneralUtilities`StringPatternQ /@ patt
System`Dump`validStringExpressionQ /@ patt
Quiet@Check[StringMatchQ["s", #], $Failed] & /@ patt
{True, True, True, True, True, False, False} {True, True, True, True, False, False, False} {True, True, True, True, $Failed, $Failed, $Failed}
Leonid's example:
stpatt = "**";
System`Dump`validStringExpressionQ[stpatt] (* ==> False *)
System`Dump`validStringExpressionQ[Evaluate[stpatt]] (* ==> True *)
GeneralUtilities`StringPatternQ[stpatt] (* ==> True *)
GeneralUtilities`StringPatternQ[Evaluate[stpatt]] (* ==> True *)
According to its PrintDefinitions
, it recognizes the following arguments as string patterns:
spq[e_Alternatives] := AllTrue[e, spq];
spq[e_List] := AllTrue[e, spq];
spq[_String] := True;
spq[DatePattern[e_List]] := Developer`StringVectorQ[e];
spq[DatePattern[e_List, sep_]] := Developer`StringVectorQ[e] && spq[sep];
spq[Verbatim[Longest][e_]] := spq[e];
spq[Verbatim[Shortest][e_]] := spq[e];
spq[Verbatim[Repeated][e_, ___]] := spq[e];
spq[Verbatim[RepeatedNull][e_]] := spq[e];
spq[Verbatim[Except][e_]] := spq[e];
spq[Verbatim[Except][e_, f_]] := spq[e] && spq[f];
spq[Verbatim[Pattern][_, patt_]] := spq[patt];
spq[Verbatim[Verbatim][_String]] := True;
spq[Verbatim[Condition][patt_, _]] := spq[patt];
spq[Verbatim[PatternTest][patt_, _]] := spq[patt];
spq[e_AnyOrder] := AllTrue[e, spq];
spq[e_FixedOrder] := AllTrue[e, spq];
spq[expr_] := MatchQ[expr, $AtomicPatterns];
-
$\begingroup$ The
$AtomicPatterns
isGeneralUtilities`Strings`PackagePrivate`$AtomicPatterns
. $\endgroup$– Karsten7Commented Nov 28, 2015 at 10:45
System`Dump`validStringExpressionQ
This function calls StringMatchQ
. Only if StringMatchQ
works normally, it returns True
.
Its definition is quite simple:
System`Dump`validStringExpressionQ[a_HoldPattern] :=
Quiet@Head@StringMatchQ["", StringExpression@a] =!= StringMatchQ
StringPattern`StringPatternQ
This one has a quite complex implementation, and is possibly the function called by StringMatchQ
.
GeneralUtilities`StringPatternQ
GeneralUtilities`
is a convenient package. The function here has a complex implementation (more complex than the next one), but is not quite reliable.
Unexpected behavior can be produced by:
StringPatternQ@String[]
StringPatternQ@Except@""
StringPatternQ@Condition[anything, anything]
StringPatternQ@PatternTest[anything, anything]
System`ConvertersDump`StringPatternQ
and FileFormatDump`StringPatternQ
Currently, these two functions have the same implementation (which is quite simple and less reliable):
System`ConvertersDump`StringPatternQ[x_] := MatchQ[x,
Alternatives[_String, _StringExpression, _RegularExpression, _Alternatives]
]
System`Dump`validStringExpressionQ[]
. $\endgroup$