ReplaceAll[expr, rule] and ReplaceRepeated[expr, rule] search through all subexpressions of expr applying rule where they match.

Are there built-in Mathematica functions that do the same thing, except not make any replacements inside specified Heads (that is, it shouldn't look at any subexpressions within specified Head)?

I'd imagine something like ReplaceAllRestricted[expr, rule, heads] and ReplaceRepeatedRestricted[expr, rule, heads].

  • $\begingroup$ Possible duplicate: (125746) $\endgroup$ Sep 9, 2016 at 1:31
  • 1
    $\begingroup$ @JHM actually, I'd close the other one in favor of this one, as it is more general. $\endgroup$
    – rcollyer
    Sep 9, 2016 at 3:25
  • $\begingroup$ A possibility is to use Developer`ReplaceAllUnheld $\endgroup$
    – QuantumDot
    Sep 25, 2016 at 21:03

1 Answer 1


You could exploit the fact that Replace and its derivatives do not match the same pattern twice in one iteration. Thus:

ReplaceAllRestricted[expr_, rules_List, heads_List] :=
 expr /. Join[a : Blank[#] :> a & /@ heads, rules];

ReplaceAllRestricted[{a[1], b[1], c[1]}, {1 -> 3}, {c}]

{a[3], b[3], c[1]}


ReplaceRepeatedRestricted[expr_, rules_List, heads_List] := 
 expr //. Join[a : Blank[#] :> a & /@ heads, rules];

ReplaceRepeatedRestricted[{a[a[a[1]]], b[b[b[1]]]}, {_[1] -> 1}, {b}]

{1, b[b[b[1]]]}

a : Blank[#] :> a & /@ heads adds non-functional replacement rules that replaces a pattern with some head with itself.

However, when you run the code, because Mathematica 'replaced' the pattern (with the pattern itself), it does not further replace the sub-expressions.

  • 1
    $\begingroup$ I really like this. If you don't mind, I have added "_List" to the final two arguments in the LHS of your definitions to suggest usage. Feel free to roll back. $\endgroup$
    – QuantumDot
    Sep 9, 2016 at 16:59

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.