6

Possible Duplicate:
Regex replacements inside a StringBuilder

What is the best way to do a Regex Replace, many times, on StringBuilder?

If you don't mind NOT being a tl;dr person, read further for details:

Hi, I have a function that does quite a lot of string manipulations on a string. So naturally, I am using StringBuilder class for it. Now I am in quite a dilemma.

My function is something like this:

 ParsedText.Append("some footers here");
 ParsedText.Replace("[b]","<b>"); //format all bold opens
 ParsedText.Replace("[/b]","</b>"); //format all bold closes
 ParsedText.Replace("\n","<br />"); //format newlines

 .... sh!* load of other replaces and manipulations ...

 //Add <a href> to all links
 ParsedText = new StringBuilder(Regex.Replace(ParsedText, "pattern", "replacement"))

And now, I have a.. custom list of words (patterns) that I would want to replace - about 20 patterns..

I am trying to replace all smiley symbols with their respective images; like so:

:) becomes <img src="smile.png" />
;) becomes <img src="wink.png" />

and etc...I have about 20 images / symbols to replace and I am using this regex

(?<=^|\s):d(?=$|\s) //positive lookahead and lookback at :d

which Bob Vale kindly provided.

All this is great, except, I don't know how to regex replace with StringBuilder and I don't want to create a new StringBuilder like so:

 ParsedText = new StringBuilder(Regex.Replace(...));

twenty times as I think it defeats the whole memory conservation purpose.

So, What is the best way to do a Regex Replace on StringBuilder?

Thanks!

Community
  • 1
  • 1
LocustHorde
  • 6,361
  • 16
  • 65
  • 94
  • 2
    I think you're missing the point of `StringBuilder`. It provides `O(n)` string concatenation rather than `O(n^2)`, when concatenating many strings. That's just about it. – Matt Ball Jul 22 '11 at 14:36
  • @Matt Ball, sorry for sounding stupid, what does O(n) and O(n^2) mean? – LocustHorde Jul 22 '11 at 15:35
  • 3
    It's called Big O notation. In this case, it means that as the number of items (or length of the string) gets larger, the time or memory to append them will increase linearly instead of exponentially. – Joel Coehoorn Jul 22 '11 at 15:49
  • "If you don't mind being a tl;dr person, read further for details:" I don't think you get what tl;dr means. ಠ_ಠ – BoltClock Jul 22 '11 at 15:52

2 Answers2

3

The simplest way to do this is to refactor your existing filters out to a method you can call to run all the filters at once. Once that is done, you can change the code to start calling this method for the smaller string every time you append to the stringbuilder before the new string is added, rather than waiting until the end and having to build the large string multiple times. This is important because it can save you from running into problems with Large Object Heap down the road, and is otherwise a lot more garbage-collector friendly.

Once you get that far, if you're really ambitious you can also re-write to start using streams rather than a stringbuilder. That will allow you to combine a number of your filters into a custom, highly-efficient state machine that should have a measurable positive impact on performance. But this last step will come at the cost of code clarity and easy maintenance, so don't do it unless you see this code as driving the performance of your app.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
1

See this question and advice from Jon Skeet:

The best and most efficient solution for your time is to try the simplest approach first: forget the StringBuilder and just use Regex.Replace.

Community
  • 1
  • 1
VMAtm
  • 27,943
  • 17
  • 79
  • 125