Хотите кодировать текст во время вызова Regex.Replace - PullRequest
4 голосов
/ 05 сентября 2008

У меня есть вызов regex, с которым мне нужна помощь.

Я не разместил свое регулярное выражение, потому что оно здесь неактуально. Я хочу, чтобы во время замены я также хотел изменить часть $ {test}, выполнив Html.Encode для всего текста, который влияет на регулярное выражение.

По сути, оберните весь текст, находящийся в пределах диапазона регулярного выражения, жирным тэгом, а также Html. Кодируйте текст между жирным тэгом.

RegexOptions regexOptions = RegexOptions.Compiled | RegexOptions.IgnoreCase;
text = Regex.Replace(text, regexBold, @"<b>${text}</b>", regexOptions);

Ответы [ 5 ]

4 голосов
/ 06 сентября 2008

Существует невероятно простой способ сделать это (в .net). Его называют MatchEvaluator, и он позволяет вам делать все, что угодно, найти и заменить. По сути, вы просто передаете методу Regex.Replace имя метода метода, который возвращает строку и принимает в качестве единственного параметра объект Match. Делайте все, что имеет смысл для вашего конкретного совпадения (html encode), и возвращаемая вами строка заменит весь текст совпадения во входной строке.

Пример. Допустим, вы хотите найти все места, где добавляются два числа (в тексте), и хотите заменить выражение на фактическое число. Вы не можете сделать это со строгим подходом регулярных выражений, но вы можете, когда вы добавляете MatchEvaluator, это становится легко.

public void Stuff()
{
    string pattern = @"(?<firstNumber>\d+)\s*(?<operator>[*+-/])\s*(?<secondNumber>\d+)";
    string input = "something something 123 + 456 blah blah 100 - 55";
    string output = Regex.Replace(input, pattern, MatchMath);
    //output will be "something something 579 blah blah 45"
}

private static string MatchMath(Match match)
{
    try
    {
        double first = double.Parse(match.Groups["firstNumber"].Value);
        double second = double.Parse(match.Groups["secondNumber"].Value);
        switch (match.Groups["operator"].Value)
        {
            case "*":
                return (first * second).ToString();
            case "+":
                return (first + second).ToString();
            case "-":
                return (first - second).ToString();
            case "/":
                return (first / second).ToString();
        }
    }
    catch { }
    return "NaN"; 
}

Узнайте больше на http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.matchevaluator.aspx

3 голосов
/ 05 сентября 2008

Не используйте Regex.Replace в этом случае ... используйте ..

foreach(Match in Regex.Matches(...))
{
    //do your stuff here
}
2 голосов
/ 06 сентября 2008

Вот реализация этого, которую я использовал, чтобы выбрать специальные строки замены из контента и локализовать их.

        protected string FindAndTranslateIn(string content)
        {
            return Regex.Replace(content, @"\{\^(.+?);(.+?)?}", new MatchEvaluator(TranslateHandler), RegexOptions.IgnoreCase);
        }

public string TranslateHandler(Match m)
{
    if (m.Success)
    {
        string key = m.Groups[1].Value;
        key = FindAndTranslateIn(key);
        string def = string.Empty;
        if (m.Groups.Count > 2)
        {
            def = m.Groups[2].Value;
            if(def.Length > 1)
            {
                def = FindAndTranslateIn(def);
            }
        }

        if (group == null)
        {
            return Translate(key, def);
        }
        else
        {
            return Translate(key, group, def);
        }
    }
    return string.Empty;
}

От делегата оценщика совпадений вы возвращаете все, что хотите заменить, поэтому, если я получу возврат, у вас будут полужирные теги и вызов кодирования, мой также поддерживает рекурсию, поэтому немного сложнее для ваших нужд, но вы можете просто сократить пример для ваших нужд.

Это эквивалентно выполнению итерации по сбору совпадений и выполнению частей задания методов замены. Это просто сохраняет вам некоторый код, и вы можете использовать причудливый делегат shmancy.

0 голосов
/ 05 сентября 2008

Можете ли вы ввести код внутри {}, чтобы добавить жирный тег и кодировать текст? Я запутался в том, как применить изменения ко всему текстовому блоку И заменить в конце текстовую переменную.

0 голосов
/ 05 сентября 2008

Если вы выполняете Regex.Match, результирующая группа объектов совпадения с 0-м индексом является подмножеством intput, которое соответствует регулярному выражению.

Вы можете использовать это для сшивания жирным шрифтом и кодирования там.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...