# Using ReplaceAll to change terms that match a pattern

Suppose I have a list like {a,b [Subscript[e, 1],c [Subscript[e, 1,2]. (1) Sometimes I need to replace the e-subscripted terms, (2) sometimes I need to replace terms not having an e-subscripted factor. I found that MatchQ will correctly identify terms that match the pattern, and MatchQ===False will correctly identify terms that do not match the pattern. So far, so good.

But, when I use ReplaceAll, MatchQ will work correctly, but while MatchQ===False correctly replaces terms that do not match the pattern, it returns some level-2 nonsense for terms that do match the pattern.

Say I wish to square terms that match the pattern. The code that works is b Subscript[e, 1] /. x_ :> x^2 /; MatchQ[x, _ Subscript[e, __]]. It returns Times[Power[b,2],Power[Subscript[e, 1],2]. With 'a' it returns a. The MatchQ===False code that works with 'a' is a /. x_ :> x^2 /; MatchQ[x, _ Subscript[e, __]] === False]. It returns a^2. But, with b [Subscript[e, 1] it returns Power[Times,2] Power[b,2],Power[Subscript[e, 1], 2]]. It should just return the input, b [Subscript[e, 1. MatchQ does not accept an input for level, so I tried using FreeQ, which does, but no matter what level I try, it gives the same answer as MatchQ===False.

I am open to another approach if this is not a good way to go. I know that subscripts are discouraged in Mathematica but I am of the philosophy that it is up to the code developer to take on the burdern to generate code that the user is familiar with rather than making the user have to adapt. All of my output is in standard mathematical form. I would appreciate any help you guys can give me.

• It would be much more helpful if you could include the desired outputs together with the actual ones. It is unclear to me in your examples what you would like the code to do. Could you also check the return value Power[Times,2] Power[b,2],Power[Superscript[e, 1], 2]] you quoted? There seems to be maybe a stray comma in there. – MarcoB Jan 22 at 3:41
• MarcoB, thank you for your reply. I replaced Superscrpt with Subscript. Sorry. It was hard for me to type all this in. To answer your other question, two of the cases simply return the input term, unchanged. The other two cases square the input term. I'll work with Roma's suggestions tomorrow and see if I can get this to work. – matrixbud Jan 22 at 4:41

ReplaceAll replaces all parts of the expression, use Replace instead. Also the pattern x_/;MatchQ[x,pat] is better to replace by x:pat, while x_/;MatchQ[x,pat]===False (or x_/;!MatchQ[x,pat]) by x:Except[pat] . Consider

In[1]:=
Replace[{a, b Subscript[e, 1], c Subscript[e, 1, 2]}, x:(b Subscript[e, __]) :> x^2, {1}]
Out[1]:={a, b^2*Subscript[e, 1]^2, c*Subscript[e, 1, 2]}


and

In[2]:=
Replace[{a, b Subscript[e, 1], c Subscript[e, 1, 2]}, x:Except[(b Subscript[e, __])] :> x^2, {1}]
Out[2]:={a^2, b*Subscript[e, 1], c^2*Subscript[e, 1, 2]^2}


The third argument of Replace denotes the level --- consult Mathematica Help.

• Roma, This works perfectly. Exactly what I was looking for. I am self-taught, just using the Documentation Center help, and I was unaware of Replace . Also, I had never seen the x:pat notation but it is much more compact than MatchQ. Similarly, I hadn't figured out to write !MatchQ rather than MatchQ===False. Thank you for those tips. I replaced your two instances of b Subscript with _ Subscript. I am pretty sure that is what you meant, and it works. Thank you so much. I consider this question to be fully answered. The documentation on x:pat led me to Optional` and is skimpy – matrixbud Jan 23 at 3:44