7
$\begingroup$

I want to delete the string representing the context of a symbol. For info I need such a functionality in my ShowIt function defined here

I'd like to know how I can replace such a string with a rule so that for example,

"MyFunc[ShowIt[Q1`Private`var1$123], ShowIt[Q2`Private`var2$456], 0., 1.]"

gives

"MyFunc[ShowIt[var1], ShowIt[var2], 0., 1.]"

or

"Q1`Private`var1$123"

gives

"var1"
$\endgroup$

2 Answers 2

5
$\begingroup$

Trying to detect and replace strings that represent symbols is problematic. Essentially you need to parse the string as an expression to be robust, and that it better done with built-in parsing than with StringReplace.

Documentation for SymbolName says:

SymbolName always gives the short name, without any context.

Therefore you may use:

short =
  Module[{T, SR = StringReplace[#, a__ ~~ "$" ~~ DigitCharacter .. :> a] &},
    With[{ME = MakeExpression, U = Unevaluated},
     ME @ #
       /. s_Symbol :> T @ ME @ SR @ SymbolName @ U @ s
       /. T@_@x_   :> x
       /. _@x_     :> U@x ~ToString~ InputForm
  ]] &;

short @ "MyFunc[ShowIt[Q1`Private`var1$123], ShowIt[Q2`Private`var2$456], 0., 1.]"
"MyFunc[ShowIt[var1], ShowIt[var2], 0., 1.]"
short @ "MyFunc[ShowIt[\"Not`a`symbol\"], ShowIt[Q2`Private`var2$456], 0., 1.]"
"MyFunc[ShowIt[\"Not`a`symbol\"], ShowIt[var2], 0., 1.]"

Of course the string may change somewhat because of the parse and string conversion, much as doing Cell > Convert To... (form) does, but if this string is already automatically generated that should not be a problem.


Now that I have seen your application inside ShowIt it seems clear that you should avoid the conversion to a String in the first place.

Where you are using:

ExtactSymbolName[str_String]:=
    With[{pat = WordCharacter},
        StringReplace[str, (pat ... ~~ "`") .. ~~ s : pat .. ~~ ("$" ~~ NumberString) ... :> s]
    ];

ToExpression[ ExtactSymbolName @ ToString @ Unevaluated @ expr, InputForm, Defer]

I would use:

Module[{T, SR = StringReplace[#, a__ ~~ "$" ~~ DigitCharacter .. :> a] &},
  Defer[expr]
    /. s_Symbol :> T @ MakeExpression @ SR @ SymbolName @ Unevaluated @ s
    /. T@_@x___ :> x
]
$\endgroup$
4
  • $\begingroup$ Thank Mr. Wizard I'll have a curious look at you answer after sleeping. $\endgroup$
    – faysou
    Aug 5, 2012 at 3:31
  • $\begingroup$ Hmmm. I was looking for SymbolName about 2 months ago. :P $\endgroup$
    – rcollyer
    Aug 20, 2013 at 13:49
  • $\begingroup$ @rcollyer Why didn't you ask the Great and Powerful Wizard? :^) (But don't be disappointed by the man behind the curtain.) $\endgroup$
    – Mr.Wizard
    Aug 20, 2013 at 15:00
  • 1
    $\begingroup$ My method was a bit more crude, as I was converting to a string representation, but it was effective. As to looking behind the curtain, I prefer to be invited, first, otherwise it is just impolite. :) $\endgroup$
    – rcollyer
    Aug 20, 2013 at 15:09
4
$\begingroup$

I wrote something very similar to what you want in this answer. Modifying the core of the answer there to also handle temporary variables from Module, you can do:

str = "MyFunc[ShowIt[Q1`Private`var1$123],ShowIt[Q2`Private`var2$456],0., 1.]";    
With[{pat = WordCharacter},
    StringReplace[str, (pat ... ~~ "`") .. ~~ s : pat .. ~~ ("$" ~~ NumberString) ... :> s]
]

(* "MyFunc[ShowIt[var1],ShowIt[var2],0.,1.]" *)
$\endgroup$
3
  • $\begingroup$ Great thank you very much $\endgroup$
    – faysou
    Aug 3, 2012 at 15:44
  • $\begingroup$ (LetterCharacter | DigitCharacter) is just the same as WordCharacter, no? $\endgroup$ Aug 3, 2012 at 22:12
  • $\begingroup$ yup $\phantom{}$ $\endgroup$
    – rm -rf
    Aug 3, 2012 at 23:03

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.