Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I am trying to format some text based on some patterns.

Clear[highlight];
SetAttributes[highlight, HoldAll];
highlight[pattern_, style_] := 
  s_String :> Row[List @@ StringReplace[s, t : pattern :> style[t]]]

This works fine and dandy if a match is found:

"foo bar baz" /. highlight["foo", Style[#, Red] &]

But doesn't if no match is found:

"fu bar baz" /. highlight["foo", Style[#, Red] &]

Row["fu bar baz"]

The failure to match has left us with an ugly Row. I'm having a bit of trouble fixing this case, perhaps you can help?

share|improve this question

2 Answers 2

up vote 7 down vote accepted

Here is what I'd do:

Clear[highlight];
SetAttributes[highlight, HoldAll];
highlight[pattern_, style_] :=
  s_String :>
     With[{replaced = StringReplace[s, t : pattern :> style[t]]},
         Row[List @@ replaced] /; replaced =!= s]

What happens here is that I use the variable replaced shared between the body of With and the condition. This is a very handy construct in many cases. It has the effect that while we do some computations in the body, at the end the rule may be considered not matched by the pattern-matcher. This is often convenient in cases when the fact of the match requires some computations, to be established.

This form has also a global version, which has many applications as well, inlcuding the Trott-Strzebonski in-place evaluation technique, discussed e.g. here.

share|improve this answer

Update: I believe the best way is to use Apply, exploiting the behavior that f @@ x yields x when x is atomic (like a String). Therefore with the code below a raw string remains a string, whereas a StringExpression is converted to a Row.

Clear[highlight];
SetAttributes[highlight, HoldAll];

highlight[pattern_, style_] := 
  s_String :> (Row[{##}] & @@ StringReplace[s, t : pattern :> style[t]])

Test:

{"foo bar baz", "fu bar baz"} /.
  highlight["foo", Style[#, Red] &]

enter image description here

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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