# Pattern matching with DeleteCases

I'm using Mathematica 14.0 and I'm having a pattern match problem with DeleteCases. The example below illustrates the problem. I define a test string followed by two patterns that both nominally match the test string. Next the test string and both patterns are used with DeleteCases and StringReplace. For DeleteCases pattern1 matches and the string is deleted but for pattern2 the pattern does not match and the string is not deleted. For StringReplace both patterns match and the string is replaced with theta.

Why does pattern2 not match for DeleteCases?

Input:

testString = "2 -> ";
pattern1 = "2" ~~ " " ~~ "->" ~~ " ";
pattern2 = _ ~~ " " ~~ "->" ~~ " ";
DeleteCases[{testString}, pattern1 ]
DeleteCases[{testString}, pattern2 ]
StringReplace[{testString}, pattern1 -> "\[Theta]" ]
StringReplace[{testString}, pattern2 -> "\[Theta]" ]

Output:

{}
{"2 -> "}
{"\[Theta]"}
{"\[Theta]"}

String matching is different than general pattern matching. Let's look at the full form of the expressions:

FullForm[pattern1]
(* "2 -> " *)

FullForm[pattern2]
(* StringExpression[Blank[]," -> "] *)

So, pattern1, since there were no actual placeholders (Blanks), just evaluated to a plain string. And so if used as a pattern it will match literally, i.e. only strings of the exact same form. pattern2 didn't simplify all the way to a plain string. StringExpressions are used for string matching. So, if you use it as a general pattern (like you're trying with DeleteCases, then it will only match other StringExpressions. But of course, your testString is not a StringExpression.

A very convoluted workaround would be:

DeleteCases[{testString}, _?(StringMatchQ[pattern2])]
(* {} *)

A simpler workaround would be

Select[{testString}, Not@*StringMatchQ[pattern2]]
(* {} *)