Remove subscript from string
A slightly more general version of JasonB's solution:
deSubscript[string_] := StringReplace[string,
"\!\(\*SubscriptBox[\(" ~~ Shortest[x__] ~~ "\), \(" ~~
Shortest[y__] ~~ "\)]\)" :> x <> y
];
which also works if the string contains something other than a single SubscriptBox
:
In[243]:= subscriptBoxToString["\!\(\*SubscriptBox[\(aH\), \(2\)]\)\!\
\(\*SubscriptBox[\(123\), \(3\)]\)"]
subscriptBoxToString["\!\(\*SubscriptBox[\(C\), \(2\)]\) \
\!\(\*SubscriptBox[\(NH\), \(3\)]\)"]
subscriptBoxToString["\!\(\*SubscriptBox[\(CO\), \(2\)]\)"]
Out[243]= "aH21233"
Out[244]= "C2 NH3"
Out[245]= "CO2"
This would need to be modified for other forms, but it does what you are asking
deSubscript =
StringReplace[#,
"\!\(\*SubscriptBox[\(" ~~ var__ ~~ "\), \(" ~~ sub_ ~~ "\)]\)" :>
var <> sub] &;
gases = {"Air", "He", "Ar", "\!\(\*SubscriptBox[\(N\), \(2\)]\)",
"\!\(\*SubscriptBox[\(CO\), \(2\)]\)"};
deSubscript[gases]
(* {"Air", "He", "Ar", "N2", "CO2"} *)
The most straightforward approach is to convert your string representation of boxes into explicit boxes, and then apply a replacement rule. The internal function which does this was uncovered by John Fultz:
stringToBoxes[s_String] :=
MathLink`CallFrontEnd[FrontEnd`UndocumentedTestFEParserPacket[s, False]][[1, 1]]
Now
stringToBoxes /@ gases /. SubscriptBox[x_, y_] :> x <> y
{"Air", "He", "Ar", "N2", "CO2"}
Note that this approach won't lead to evaluation leaks if symbols with names Air
, He
etc. have values because these names are kept as strings during the conversion.
The above solution can be easily generalized for handling more complicated 2D labels, for example:
label = "\!\(\*SubscriptBox[\(N\), \({1,2,3}\)]\)"
Replace[stringToBoxes@label,
box : _RowBox | _SubscriptBox | _SuperscriptBox :> StringJoin @@ box, {0, Infinity}]
"N{1,2,3}"