Suppose I have several types of expressions (in some random order) of the form

Power[Subscript[g, a], μ] which is $g_a{}^\mu$

Subscript[Power[g, a], α]] which is $g^a{}_\alpha$

Power[g, Times[ρ, θ]] which is $g^{\rho\theta}$

Subscript[Subscript[g, a], α] which is $g_{a \alpha}$

I need to extract subscript and superscript regardless of the type of the expression.


3 Answers 3

exprs = {Power[Subscript[g, a], μ ], Subscript[Power[g, a], α ],
         Power[g, Times[ρ, θ] ], Subscript[Subscript[g, a], α] }

Cases[#, (Power | Subscript)[_, y_] :> y, {0, Infinity}]&/@ exprs
(* {{a, μ}, {a, α}, {θ ρ}, {a, α}} *)

Update: To get separate lists of powers and subscripts:

{powers, subscripts} = Function[{head}, Cases[#, head[_, y_] :> y, {0, Infinity}] & /@ exprs] /@ 
                       {Power, Subscript}
(* {{{μ}, {a}, {θ ρ}, {}}, {{a}, {α}, {}, {a, α}}} *)
  • $\begingroup$ Thank you very much! But in this case $g_{ab}$ and $g^{ab}$ give the same output $\{a b\}$. They should be distinguishable $\endgroup$
    – Yuri
    Commented Feb 11, 2015 at 5:01
  • 1
    $\begingroup$ @g3n1uss, please see the update. $\endgroup$
    – kglr
    Commented Feb 11, 2015 at 5:08
  • $\begingroup$ Great! Thank you very much! $\endgroup$
    – Yuri
    Commented Feb 11, 2015 at 5:15

You did not specify an output format. Nevertheless I propose:

f[b_^su_ | Subscript[b_, sb_]] :=
  Join[f@b, {Up[su], Down[sb]}] ~Cases~ _[_]

f[else_] := {}


test = {
  Power[Subscript[g, a], μ],
  Subscript[Power[g, a], α],
  Power[g, Times[ρ, θ]],
  Subscript[Subscript[g, a], α]

f /@ test
{{Down[a], Up[μ]}, {Up[a], Down[α]}, {Up[θ ρ]}, {Down[a], Down[α]}}

Up and Down serve to label superscripts and subscripts.


I propose to use a custom structure

add[{a___}, (List | Times)[b___] | c_] := {b, c, a}
script[a_^b_, sub_: {}, sup_: {}] := script[a, sub, add[sup, b]];
script[Subscript[a_, b_], sub_: {}, sup_: {}] := script[a, add[sub, b], sup];

script /@ exprs
(*{script[g, {a}, {μ}], script[g, {α}, {a}], script[g, {}, {θ, ρ}], script[g, {a, α}, {}]}*)

It is very clear and allows you further pattern-matching and other abilities.

Also you can add custom formatting

script /: MakeBoxes[script[g_, sub_, sup_], StandardForm] := 
 SubsuperscriptBox[ToBoxes@g, RowBox[ToBoxes /@ sub], RowBox[ToBoxes /@ sup]]

to display the result as

enter image description here


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.