Search code examples
vb.netstringreplacecontentplaceholder

vb.net string - replace placeholder tokens efficiently


I'm just looking for some ideas with a little problem. I've a string that's a template for a message, for example:

Dear [[Guest.FirstName]],

We hope your are looking forward to your holiday in [[Booking.ResortName]]

My current system for replacing the spaceholder tokens (e.g. [[Guest.FirstName]]) is very inefficient, there's loops inside loops and it takes for too long.

What I'm looking for is a way that would go through the string until it finds [[something]], then replace that [[something]] with it's real value, then continue on through the string.

Please note to replace [[something]] then I need to have access to the space holder (i.e. i need to know if it's [[Guest.FirstName]] or [[Booking.ResortName]]).

Any suggestions for an efficient way to achieve this would be very much appreciated, I feel it should be fairly straightforward but everything I can think of ends up with loops inside loops again.

Thanks!

Phil.


Solution

  • There are many factors which will affect performance, so it's hard to say, without knowing all the specifics, what method will be most efficient. However, when it comes to coding simplicity, using a RegEx MatchEvaluator would be an excellent option. I'm sure you'll agree that it's much cleaner than whatever you are currently using:

    Public Function ReplacePlaceholders(data As String) As String
        Dim r As New Regex("\[\[(?<placeholder>.*?)\]\]")
        data = r.Replace(data, New MatchEvaluator(AddressOf PlaceHolderReplacementEvaluator))
    End Function
    
    Private Function PlaceHolderReplacementEvaluator(match As Match) As String
        Dim name As String = match.Groups("placeholder").Value
        Return LookUpValueByPlaceholderName(name)   ' Replace with value lookup logic here
    End Function
    

    If the total number of placeholders in the data is going to be rather small, and the list of possible placeholders is small, it's probably best to just have a list of them with their values and replace them like this:

    Public Function ReplacePlaceholders(data As String) As String
        Dim placeHolders As Dictionary(Of String, String) = LoadPlaceHolders()
        For Each i As KeyValuePair(Of String, String) In placeHolders
            data = data.Replace(i.Key, i.Value)
        Next
        Return data
    End Function
    
    Private Function LoadPlaceHolders() As Dictionary(Of String, String)
        Dim placeholders As New Dictionary(Of String, String)
        ' Load data here
        Return placeholders
    End Function
    

    If you really want the most efficient solution, though, going character by character and appending, as you go, to a StringBuilder or an output Stream, is going to be your best option. It's not going to be pretty, but if you post what you have to CodeReview, there may be some people who could find ways of making it slightly less ugly :)