Replace part of a variable name (or even part of a number) [duplicate]

I want to replace variables like x12 and x13 with respectively x21 and x23. And I want to do this by directly replacing any 2's found with 1's and vice versa. Now I realize that the preferred way to do this is different. For instance, one can store the 12 using x[12] and then exchange 12->21 and 21->12. (We still encounter the same problem that we cannot replace the actual symbols 1 and 2 directly). Or one can replace x12->x21 etc.

For most instances these methods are indeed preferable and we certainly would not want replace to always do the replacements in the manner I described, since it is prone to make unwanted replacements in all manner of ways.

However, for the simple replacements I'm thinking of I think it would be safe (no numbers elsewhere in the expressions no complicated functions that might contain numbers in their FullForm) and would save time to do the replacements by writing 1->2,2->1 instead of writing x12->x21,x13->x23 etc.

(On a small side note is there a notationally efficient way to write an exchange 1<->2? It seems this would be very useful, both to save time typing and for readability, but I couldn't find it. Sorry if asking such a side question is frowned upon.)

Note that I'm working with small expressions of these variables and I am willing to trade computational efficiency for notational efficiency.

It seems that the thing I want from replace is so close to what it normally does, that it would be strange if it would not be a simple adaption. Can we define a second replace function that works the way I want it to.

(Sure it would have been even faster if I would have just done it the conventional way instead of writing this question, but where's the fun in that).

• Can x12 and friends have values? – Kuba Jan 16 '17 at 11:19
• You could try something like this: Unevaluated[{x12}] /. x_Symbol :> Symbol[ StringReplace[ ToString[Unevaluated[x]], {"1" -> "2", "2" -> "1"} ] ] Just be sure to wrap the initial expression in Hold or Unevaluated, otherwise x12 might evaluate before the ReplaceAll can do something. – Sjoerd Smit Jan 16 '17 at 11:19
• In case of held expressions you may need to add: Replacing parts of a held expression with held parts of another expression – Kuba Jan 16 '17 at 11:34