2

Why is there a StringExpression in the following code?

f["a b c"] //. x_String :> 
    StringReplace[x, (StartOfString ~~ x1__ ~~ "b" ~~ x2__ ~~ EndOfString) :> f["BBB"]]
(*
    f[StringExpression[f[BBB]]]
*)

Though I can remove it, I'd rather it not appear in the first place, because I'm not sure this method is safe:

f["a b c"] //. x_String :> 
    StringReplace[x, (StartOfString ~~ x1__ ~~ "b" ~~ x2__ ~~ EndOfString) :> f["BBB"]] /. 
    StringExpression -> Sequence
(*
    f[f[BBB]]
*)
rm -rf
  • 88,781
  • 21
  • 293
  • 472
HyperGroups
  • 8,619
  • 1
  • 26
  • 63
  • 3
    This is clearly covered in the docs for StringReplace (point 3 under details): "If the Subscript[sp, i] in the replacements Subscript[s, i]->Subscript[sp, i] do not evaluate to strings, StringReplace will yield a StringExpression rather than an ordinary string." – rm -rf Jul 05 '13 at 05:39
  • @rm-rf oh, I see , thanks, f["a b c b "]//.x_String:>StringReplace[x,Shortest[x1__~~"b"~~x2__]:>f["BBB"]] this maybe more apparently why need StringExpression. – HyperGroups Jul 05 '13 at 05:46
  • Related: http://mathematica.stackexchange.com/q/7008/121 – Mr.Wizard Apr 14 '14 at 10:13

1 Answers1

3

As R.M. described this behavior is documented:

If the spi in the replacements si -> spi do not evaluate to strings, StringReplace will yield a StringExpression rather than an ordinary string.

I recommend stripping StringExpression as part of the right-hand side of the primary replacement, so that the main expression never has StringExpression substituted into it. A shorter replacement form, e.g. _[x_] :> x may be used as the return from StringReplace should be either a String or a StringExpression object, or you could simply Apply Sequence:

f["a b c"] //. 
 x_String :> 
  Sequence @@ 
   StringReplace[x, (StartOfString ~~ x1__ ~~ "b" ~~ x2__ ~~ EndOfString) :> f["BBB"]]

This works because Sequence @@ "string" returns "string".

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371