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].
Answer
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]}
and
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.
Comments
Post a Comment