views:

67

answers:

4

Hello, I try to use regexp in .net to find and replace strings with certain token, example

myString = "this is a example of my text that I want to change <#somevalue#> and <#anothervalue#>"

How I can find the text with tokens between "<#" and "#>" and for each of those, do something to replace it (search on a database and replace any of those found matches)?

result that I want:

myString = "this is a example of my text that I want to change someValueFromDb and anotherValueFromDb"

Thanks.

A: 

You want to use the Regex.Replace method that accepts a MatchEvaluator delegate. This delegate will allow you to dynamically provide replacement text.

Regex.Replace(yourString, @"\<\#([^#]+)\#\>", delegate(Match match)
    {
       // Your code here - use match.ToString()
       // to get the matched string
    });
Andrew Hare
I used Regex.Replace(text, "<:(.*?)>", delegate(Match match) {return match.ToString() + "test"; });but it's not changing the text, how I can do this with this delegate? thanks
FabianSilva
+1  A: 

Below is an example using Regex.Replace that uses a MatchEvaluator to perform the replacement by checking in a dictionary for the specified token. If the token isn't present in the dictionary, the text remains the same.

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace TokenReplacement
{
    class Program
    {
        static void Main(string[] args)
        {
            string text = "this is a example of my text that I want to change <#somevalue#> and <#anothervalue#>";

            var tokens = new Dictionary<string, string>
            {
                { "somevalue", "Foo" },
                { "anothervalue", "Bar" }
            };

            Console.WriteLine(Replace(text, tokens));
        }

        static string Replace(string input, Dictionary<string, string> tokens)
        {
            MatchEvaluator evaluator = match =>
            {
                string token;
                if (tokens.TryGetValue(match.Groups[1].Value, out token))
                    return token;

                return match.Value;
            };

            return Regex.Replace(input, "<#(.*?)#>", evaluator);
        }
    }
}
Chris Schmich
A: 

Solution 1

There is a fairly thorough regular expression based token replacement and documentation available here:

http://www.simple-talk.com/dotnet/asp.net/regular-expression-based-token-replacement-in-asp.net/

Solution 2

If you don't want to add that much code, here is another approach. This code looks up the tokens (formatted like #MyName#) in the configuration file AppSettings section I have used a similar approach in another project for looking them up in the resources and database (or all 3 in a specific priority). You can change the format of your tokens if you wish by changing the regular expression and string replacement lines.

Of course, this can still be tweaked for better performance by using regular expressions throughout.

Public Shared Function ProcessConfigurationTokens(ByVal Source As String) As String
    Dim page As Page = CType(Context.Handler, Page)
    Dim tokens() As String = GetConfigurationTokens(Source)
    Dim configurationName As String = ""
    Dim configurationValue As String = ""

    For Each token As String In tokens
        'Strip off the # signs
        configurationName = token.Replace("#"c, "")

        'Lookup the value in the configuration (if any)
        configurationValue = ConfigurationManager.AppSettings(configurationName)

        If configurationValue.Contains(".aspx") OrElse configurationValue.Contains("/") Then
            Try
                Source = Source.Replace(token, page.ResolveUrl(configurationValue))
            Catch
                Source = Source.Replace(token, configurationValue)
            End Try
        Else
            'This is an optimization - if the content doesn't contain
            'a forward slash we know it is not a url.
            Source = Source.Replace(token, configurationValue)
        End If
    Next

    Return Source
End Function

Private Shared Function GetConfigurationTokens(ByVal Source As String) As String()
    'Locate any words in the source that are surrounded by # symbols
    'and return the list as an array.
    Dim sc As New System.Collections.Specialized.StringCollection

    Dim r As Regex
    Dim m As Match

    If Not String.IsNullOrEmpty(Source) Then

        r = New Regex("#[^#\s]+#", RegexOptions.Compiled Or RegexOptions.IgnoreCase)
        m = r.Match(Source)
        While m.Success

            sc.Add(m.Groups(0).Value)

            m = m.NextMatch
        End While

        If Not sc.Count = 0 Then
            Dim result(sc.Count - 1) As String
            sc.CopyTo(result, 0)

            Return result
        End If
    End If

    Return New String() {}

End Function
NightOwl888
A: 

Thanks for all the responses, I found an answer on http://stackoverflow.com/questions/1265300/replace-tokens-in-an-aspx-page-on-load that is exactly what I need

Thanks for the links and examples that point me on the right direction.

private string ParseTagsFromPage(string pageContent)
    {
        string regexPattern = "{zeus:(.*?)}"; //matches {zeus:anytagname}
        string tagName = "";
        string fieldName = "";
        string replacement = "";
        MatchCollection tagMatches = Regex.Matches(pageContent, regexPattern);
        foreach (Match match in tagMatches)
        {
            tagName = match.ToString();
            fieldName = tagName.Replace("{zeus:", "").Replace("}", "");
            //get data based on my found field name, using some other function call
            replacement = GetFieldValue(fieldName); 
            pageContent = pageContent.Replace(tagName, replacement);
        }
        return pageContent;
    }
FabianSilva