How do I replace content inside a Held expression without local values coming through? For example if you run the following code you get g[2] instead of g[x](the intended form).

x = 2;
Replace[HoldComplete[g["x"]], {
  y_String :> With[{
     eval = Symbol[y]},
    eval /; True]
  }, {0, Infinity}]

The following questions are related

EDIT: Although rm-rf's trick is clever it partially works. His current code adds an additional defer to the current code.

InputForm@HoldComplete[g["x"]] /. 
  s_String :> With[{x = ToExpression[s, InputForm, Defer]}, x /; True]

returns HoldComplete[g[Defer[x]]] instead of HoldComplete[g[x]]. Ultimately you could strip out the Defers which is likely what I will end up doing.


3 Answers 3


The third argument of ToExpression with the Trott–Strzebonski can be used to do this:

HoldComplete[g["x"]] /. s_String :> 
    With[{x = ToExpression[s, InputForm, Defer]}, x /; True]
(* HoldComplete[g[x]] *)
  • $\begingroup$ Sequence might be used to get around this issue but I'm just running off intuition. $\endgroup$
    – William
    Commented Sep 15, 2013 at 17:36
  • $\begingroup$ @Liam, if that's a problem why not just strip out the Defer with a replacement /. Defer[x_] :> x $\endgroup$ Commented Sep 15, 2013 at 17:36
  • $\begingroup$ I modified your code slightly to the following. It works quit well. You are quit right I will stop posting partial questions especially to chat. $\endgroup$
    – William
    Commented Sep 15, 2013 at 21:03
  • 1
    $\begingroup$ Reference for Trott-Strzebonski : mathematica.stackexchange.com/a/29318/45020. $\endgroup$
    – Kvothe
    Commented Mar 23, 2021 at 11:17

I hope that you will give a more complete example in the question if this is not adequate. As it stands I don't see the need to mess with context but given the earlier questions I suspect your example is not representative of what you actually wish to accomplish.

For the given example you could use something like this:

x = 2;

  SetAttributes[h, HoldAllComplete];
    /. y_String :> RuleCondition[h @@ MakeExpression@y]
    /. h[x___] :> x
] // FullForm

This is better than stripping all Defer or HoldComplete heads as it will not strip heads that were not introduced by the replace operation itself.

  • $\begingroup$ +1. Just for fun: Delete[HoldComplete[g["x"]] /. y_String :> RuleCondition@MakeExpression@y, {1,1,0}] $\endgroup$
    – WReach
    Commented Sep 16, 2013 at 3:13

The following function ReplaceC evaluates the Replace in an alternative context and the strips the context back from the returned value.

ReplaceC[data_, rules_] := ToExpression@Replace[
     With[{body =
            Replace[x, rules, {0, Infinity}]
          HoldPattern[x] -> data, {0, Infinity}]
       }, Block[{$ContextPath = {"System`"}, $Context = "context`"},
    s_String :> StringReplace[s, RegularExpression["^context`"] -> ""],
    {0, Infinity}

Then you can run the following to get g[x].

ReplaceC[HoldComplete[g["x"]], {
  y_String :> With[{
     eval = Symbol[y]},
    eval /; True]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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