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$
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$
  • $\begingroup$ Thank Mr. Wizard I'll have a curious look at you answer after sleeping. $\endgroup$ – faysou Aug 5 '12 at 3:31
  • $\begingroup$ Hmmm. I was looking for SymbolName about 2 months ago. :P $\endgroup$ – rcollyer Aug 20 '13 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 '13 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 '13 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$
  • $\begingroup$ Great thank you very much $\endgroup$ – faysou Aug 3 '12 at 15:44
  • $\begingroup$ (LetterCharacter | DigitCharacter) is just the same as WordCharacter, no? $\endgroup$ – J. M. will be back soon Aug 3 '12 at 22:12
  • $\begingroup$ yup $\phantom{}$ $\endgroup$ – rm -rf Aug 3 '12 at 23:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.