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}\)]\)"

output

Replace[stringToBoxes@label, 
 box : _RowBox | _SubscriptBox | _SuperscriptBox :> StringJoin @@ box, {0, Infinity}]
"N{1,2,3}"