Мне нужна помощь в создании Regex.Replace с несколькими результатами - PullRequest
0 голосов
/ 05 августа 2010

Я создаю специальную утилиту кэширования страниц, которая использует синтаксис, такой как {Substitution:GetNonCachedData}, для получения данных, которые не должны кэшироваться. Решение очень похоже на встроенный <@ OutputCache %> материал, но не такое гибкое (мне это не нужно) и, самое главное, позволяет состояние сеанса быть доступным при извлечении некэшируемых данных.

В любом случае, у меня есть метод, который заменяет токены в html результатом статического метода, названного в теге {Substitution}.

Например, моя страница:

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

заполнит {Substitution:GetCurrentTime} результатами статического метода. Вот где происходит обработка:

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;

}

переменная template - это HTML-код с пользовательскими токенами, которые необходимо заменить. Проблема этого метода заключается в том, что каждый раз, когда я обновляю переменную template обновленным html, переменная match.Index больше не указывает на начало правильного символа, поскольку к template теперь добавлено больше символов.

Я могу придумать решение, которое работает либо путем подсчета символов и т. Д., Либо с помощью другого способа сделать это, но сначала я хочу убедиться, что нет более простого способа добиться этого с помощью объекта Regex. Кто-нибудь знает как это сделать?

спасибо!

Ответы [ 2 ]

1 голос
/ 05 августа 2010

Вы должны вызвать перегрузку Regex.Replace, которая принимает делегат MatchEvaluator.

Например:

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);
});
0 голосов
/ 05 августа 2010

Вместо использования совпадений и зацикливания результатов, установите регулярное выражение в скомпилированное и используйте один цикл соответствия в цикле while, пока он не прекратит сопоставление.

...