Improving multiple find / replace on HTML string

Posted on 2004-10-26
Last Modified: 2008-03-10
I'm trying to write some code that will be used for making HTML emails.  The problem is that the code seems to be very, very inefficient and I'd like to improve it if possible.  The code below reads a HTML file into a string then runs a number of string.replace() functions to get the correct output.  This is a very stripped down version of what I have:

      Dim sr As System.IO.StreamReader = New System.IO.StreamReader("htmlfile.htm")
      Dim s As String = sr.ReadToEnd

      s = s.Replace("##Date##", "Date value")
      s = s.Replace("##ADDRESS##", "Address value")

Below is an example of the HTML in the file (Sorry, I know this bit is a little obvious)

In my code I'm running s = s.replace() more than 10 times, and given this reads the entire string, modifies it and then writes it again I'm thinking it can't be the best way of doing it.  Can anyone think of any way that I can do all of the replacements in one go or improve the code in any way?

Thanks in advance.
Question by:Psychotext
    LVL 15

    Expert Comment

    Using a StringBuilder would most likely improve performance.

    using System.Text;

    StringBuilder sb = new StringBuilder("initial value");
    sb.Replace("1", "a");
    sb.Replace("2", "b");
    LVL 15

    Accepted Solution

    You could also do something like this:

    using System.Text;

    string[] oldVal = new string[]{"##DATE##", "##ADDRESS##"};
    string[] newVal = new string[]{DateTime.Now.ToString(), "123 Main Street"};

    StringBuilder sb = new StringBuilder(htmlString);
    for(int i = 0; i < oldVal.Length; i++)
          sb.Replace(oldVal[i], newVal[i]);

    Response.Write("The new HTML " + sb.ToString());
    LVL 2

    Author Comment

    Thanks for that.  I'll run some tests to see how it works out performance wise.
    LVL 25

    Assisted Solution

    That seems to be a hardway of reading text for e-mail. Why dont you just hard code the text and get rid of the difficulty. If you want this to be more complicated :p, you can embed your string in resource file and then read from there:

    Its not a complete code. Just an idea on how you can make it easier if you do not change your e-mail text very often:

    StringBuilder sb = new StringBuilder();
    sb.Append("Dear "+strUserName+"\r\n");
    sb.Append("Some more text \r\n");
    sb.Append("Thank you\r\n");

    myMailMessage.Body = sb.ToString();

    HTH, Nauman.
    LVL 28

    Assisted Solution

    Hi Psychotext,

    you can inprove the performance if you use Regular expressions, like

    s = Regex.Replace(s, "##DATE##", "Date value" )
    s = Regex.Replace(s, "##ADDRESS##", "Address value")

    LVL 2

    Author Comment

    nauman:  That's the way I would normally do it, but the client wants the ability to edit their own HTML files to use as a template for the HTML emails.  It'll all end in tears... ;-)
    LVL 2

    Author Comment

    Ok, testing complete.  What I did is set each way of doing it up in a sub and call the sub 500 times.  Times are taken from the trace page.  For fun I included the Nauman's HTML from scratch method too.  I was a little suprised by some of the results so I gave it all a second run (Times shown in brackets):

    Initial Code (Mine):
          Run 1:      1.683910 (1.783089)
          Run 2:      1.692010 (1.758817)
          Run 3:      1.682849 (1.709526)
          Run 4:      1.717491 (1.701330)
          Run 5:      1.687957 (1.690669)
          AVERAGE:      1.6928434 (1.7286862)

    Regex Code (mmarinov):
          Run 1:      1.688086 (1.736237)
          Run 2:      1.689304 (1.997267)
          Run 3:      1.640872 (1.745414)
          Run 4:      1.648548 (1.732736)
          Run 5:      1.654695 (1.714441)
          AVERAGE:      1.6643010 (1.785219)

    String Builder (timbo87 - Post 1):
          Run 1:      1.451863 (1.419885)
          Run 2:      1.386998 (1.396693)
          Run 3:      1.393115 (1.399178)
          Run 4:      1.385554 (1.398820)
          Run 5:      1.435610 (1.401689)
          AVERAGE:      1.4106280 (1.403253)

    Old & New (timbo87 - Post 2):
          Run 1:      1.446688 (1.420638)
          Run 2:      1.385504 (1.399974)
          Run 3:      1.386387 (1.408367)
          Run 4:      1.386811 (1.439679)
          Run 5:      1.394764 (1.395636)
          AVERAGE:      1.4000308 (1.4128588)

    HTML From Scratch (Nauman_ahmed):
          Run 1:      0.171699 (0.171120)
          Run 2:      0.122329 (0.122359)
          Run 3:      0.123531 (0.124216)
          Run 4:      0.125959 (0.126573)
          Run 5:      0.123910 (0.123147)
          AVERAGE:      0.1334856 (0.133483)

    Not a lot to call between Timbo's methods.  They both shave some time off the prodedure.   Looks like the main bottleneck (Unsurprisingly) is actually getting the file off the disk for reading.  This is fairly well demonstrated by Nauman's method and the fact it's over 10x faster than the others.

    I think I may cache the file in memory until it changes on the disk; should speed things up a fair bit.
    LVL 25

    Expert Comment

    Experts, what do you think if Psychotext creates a user control, add the HTML, and where it is needed to put the dynamically generated data, create server controls e.g. Label etc. The HTML can be grabbed from the user control easily. In the past, Aeros posted some code to get the HTML but I couldnt find that link. Will this way be little easier?

    Best, nauman.
    LVL 25

    Expert Comment

    Got the link:


    Table innerTable = new Table();
      Table mainTable = new Table();
      mainTable.Rows.Add(new TableRow());
      mainTable.Rows.Add(new TableRow());
      mainTable.Rows[0].Cells.Add( new TableCell());

      System.IO.StringWriter sw = new System.IO.StringWriter();
      HtmlTextWriter htmltw = new HtmlTextWriter(sw);
      String strHTML = sw.ToString();

    Any ideas on how we can grab the HTML from the user control?

    LVL 2

    Author Comment

    To be fair I've split the points awarded for this post as everyone helped toward the answer.

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How your wiki can always stay up-to-date

    Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
    - Increase transparency
    - Onboard new hires faster
    - Access from mobile/offline

    AJAX ModalPopupExtender has a required property "TargetControlID" which may seem to be very confusing to new users. It means the server control that will be extended by the ModalPopup, for instance, if when you click a button, a ModalPopup displays,…
    In .NET 2.0, Microsoft introduced the Web Site.  This was the default way to create a web Project in Visual Studio 2005.  In Visual Studio 2008, the Web Application has been restored as the default web Project in Visual Studio/.NET 3.x The Web Si…
    This video is in connection to the article "The case of a missing mobile phone (". It will help one to understand clearly the steps to track a lost android phone.
    Internet Business Fax to Email Made Easy - With eFax Corporate (, you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

    884 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    19 Experts available now in Live!

    Get 1:1 Help Now