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$ Nov 20 '12 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
    Nov 20 '12 at 9:51
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$ Nov 20 '12 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
    Nov 20 '12 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$ Nov 20 '12 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$
    – Karsten 7.
    Nov 28 '15 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, privacy policy and cookie policy

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