asp.netregexdonut-caching

I need help doing a Regex.Replace with multiple results


I'm building a custom page caching utility that uses a syntax like {Substitution:GetNonCachedData} to get data that's not supposed to be cached. The solution is very similar to the built-in <@ OutputCache %> stuff but not as flexible (I don't need it to be) and, most importantly, allows the session state to be available when retrieving non-cached data.

Anyway, I have a method that replaces the tokens in the html with the result of the static method named in the {Substitution} tag.

For example my page:

<html>
    <body>
      <p>This is cached</p>
      <p>This is not: {Substitution:GetCurrentTime}</p>
    </body>
</html>

will fill in the {Substitution:GetCurrentTime} with results of a static method. Here's where the processing happens:

private static Regex SubstitutionRegex = new Regex(@"{substitution:(?<method>\w+)}", RegexOptions.IgnoreCase);

public static string WriteTemplates(string template)
{
    foreach (Match match in SubstitutionRegex.Matches(template))
    {
        var group = match.Groups["method"];
        var method = group.Value;
        var substitution = (string) typeof (Substitution).GetMethod(method).Invoke(null, null);
        template = SubstitutionRegex.Replace()
    }

    return template;

}

the variable template is the html with custom tokens in it that need to be replaced. The problem with this method is that everytime I update the template variable with the updated html the match.Index variable no longer points to the right character start because of the template now has more characters added to it.

I can come up with a solution that works by either counting characters etc or some other screwball way of doing it, but I first want to make sure there's not some easier way to achieve this with the Regex object. Anyone know how to this?

thanks!


Solution

  • You should call the overload of Regex.Replace that takes a MatchEvaluator delegate.

    For example:

    return SubstitutionRegex.Replace(template, delegate(Match match) {
        var group = match.Groups["method"];
        var method = group.Value;
        return (string) typeof (Substitution).GetMethod(method).Invoke(null, null);
    });