Tell me more ×
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

up vote 5 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

I think I would use a second replacement to clean up after StringReplace.
The second pattern only matches if the first one does, because otherwise the string remains atomic.

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

highlight[pattern_, style_] := 
  s_String :> ( StringReplace[s, t : pattern :> style[t]] /. _[x__] :> Row[{x}] )
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.