Skip to main content
2 of 5
added 288 characters in body
Mr.Wizard
  • 275.2k
  • 34
  • 606
  • 1.5k
  • Patterns in Alternatives are tried in order
  • Only the first pattern that matches is "applied" to the expression.
  • Cases does not support multiple patterns outside of Alternatives.

I suppose it could be interesting to debate that design decision but nevertheless that's the way it works at this time.

You could of course search with multiple passes:

expr = f[x, g[y], z] pat = h_[c_] | h_[c_, __] | h_[__, c_, __] | h_[__, c_]; Join @@ (Cases[expr, # :> h -> c, {0, -1}] & /@ List @@ pat) 
{g -> y, f -> x, f -> g[y], f -> z} 

Or using ReplaceList and Level:

rules = # :> h -> c & /@ List @@ pat Join @@ (ReplaceList[#, rules] & /@ Level[expr, {0, -1}]) 

Since neither of these is efficient you could subvert the normal evaluation by using side-effects, e.g. with Condition:

Module[{f}, Scan[(f[#] := 1 /; Sow[h -> c]) &, pat]; Reap[Scan[f, expr, {0, -1}]][[2, 1]] ] 
{g -> y, f -> x, f -> g[y], f -> z} 

Or much more cleanly, though perhaps rather enigmatically, using Alternatives and Cases:

Reap[Cases[expr, pat :> 1 /; Sow[h -> c], {0, -1}];][[2, 1]] 
{g -> y, f -> x, f -> g[y], f -> z} 
Mr.Wizard
  • 275.2k
  • 34
  • 606
  • 1.5k