9
$\begingroup$

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.

$\endgroup$
2
  • 4
    $\begingroup$ Have a look at System`Dump`validStringExpressionQ[]. $\endgroup$ Commented Nov 20, 2012 at 9:46
  • $\begingroup$ Yes that's the kind of built-in function I was looking for thanks. Maybe you could put the comment as an answer. $\endgroup$
    – faysou
    Commented Nov 20, 2012 at 9:51

4 Answers 4

9
$\begingroup$

At Faysal's behest: there's the (undocumented) function System`Dump`validStringExpressionQ[]:

System`Dump`validStringExpressionQ["**"]
   True

System`Dump`validStringExpressionQ[_ ~~ 1]
   False
$\endgroup$
3
  • $\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$
    – faysou
    Commented 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] returns False, while System`Dump`validStringExpressionQ[Evaluate[stpatt]] returns True. I would prefer to get True in both cases. $\endgroup$ Commented Nov 20, 2012 at 10:33
8
$\begingroup$
StringPatternQ[_String | _StringExpression | _RegularExpression] = True;
StringPatternQ[_] = False;
$\endgroup$
5
$\begingroup$

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];
$\endgroup$
1
  • $\begingroup$ The $AtomicPatterns is GeneralUtilities`Strings`PackagePrivate`$AtomicPatterns. $\endgroup$
    – Karsten7
    Commented Nov 28, 2015 at 10:45
0
$\begingroup$

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]
]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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