TOC

This article has been localized into Russian by the community.

Стандартные Выражения (Regex):

Поиск/Замена с классом Regex

Мы уже обсуждали класс Regex и как его использовать, когда мы хотим выполнить поиск по строке в предыдущей статье. Регулярные выражения отлично подходят для этого, но другой вариант использования, когда вы хотите выполнить операции поиска/замены, где вы хотите найти определенный шаблон и заменить его чем-то другим. Класс String уже имеет метод Replace (), но он хорош только для выполнения простого поиска. При использовании регулярных выражений можно использовать силу поиска регулярных выражений и даже использовать анализируемые группы как часть строки замены. Это звучит сложно? Не волнуйтесь, мы начнем с простого примера, а затем постепенно перейдем к более продвинутым вариантам использования.

Как в предыдущей статье все примеры подразумевают наличие важных пространств имен RegularExpressions таких, как это:

using System.Text.RegularExpressions;

Теперь давайте попробуем работать с заменой строк на основе регулярных выражений. Мы будем использовать метод Replace(), находящийся в классе Regex:

string testString = "<b>Hello, <i>world</i></b>";
Regex regex = new Regex("<[^>]+>");
string cleanString = regex.Replace(testString, "");
Console.WriteLine(cleanString);

В этом примере показан очень упрощенный подход к удалению HTML-тегов из строки. Мы сопоставляем все, что окружено набором угловых скобок (< & gt;), а затем используем метод Replace() для замены каждого вхождения пустой строки, в основном удаляя HTML-теги из тестовой строки.

Замена анализируемыми значениями

Но предположим, что вы на самом деле не хотите их удалять, но вместо этого вы хотите преобразовать теги во что-то, что не будет интерпретироваться браузером, например, заменив угловые скобки (<>) квадратными скобками ([]). Именно здесь регулярные выражения действительно показывают свою силу, потому что на самом деле это очень легко, как показано в этой слегка переписанной версии нашего предыдущего примера:

string testString = "<b>Hello, <i>world</i></b>";
Regex regex = new Regex("<([^>]+)>");
string cleanString = regex.Replace(testString, "[$1]");
Console.WriteLine(cleanString);

На самом деле я просто изменил две незначительные детали: я добавил набор скобок в регулярное выражение, чтобы создать группу анализа, по существу захватив значение между угловыми скобками в первую анализируемую группу. В методеReplace () я ссылаюсь на это, используя специальную нотацию$1 , что в основном означает только группу анализа номер 1. Теперь наши выходные данные будут выглядеть следующим образом:

[b]Hello, [i]world[/i][/b]

Именованные анализируемые группы

Конечно, вы можете делать точно то же самое, используя именованные анализируемые группы (обсуждаемые в предыдущей статье), как этот:

string testString = "<b>Hello, <i>world</i></b>";
Regex regex = new Regex("<(?<tagName>[^>]+)>");
string cleanString = regex.Replace(testString, "[${tagName}]");
Console.WriteLine(cleanString);

Используя именованные анализируемые группы, просто примените нотацию ${name-of-capture-group}.

Использование метода MatchEvaluator

Но если мы хотим еще больше контроля над тем, как значение заменяется? Для этого мы можем использовать параметр MatchEvaluator - это в основном просто ссылка (делегат) на метод, который будет вызываться каждый раз при замене, что позволяет изменять заменяемое значение перед его использованием. Давайте придерживаться примера HTML-тегов, который мы уже использовали пару раз, но на этот раз мы контролируем, какие HTML-теги используются. Вот полный пример:

using System;
using System.Text.RegularExpressions;

namespace RegexSearchReplaceMethod
{
    class Program
    {
static void Main(string[] args)
{
    string testString = "<b>Hello, <i>world</i></b>";
    Regex regex = new Regex("<(?<tagName>[^>]+)>");
    string cleanString = regex.Replace(testString, ProcessHtmlTag);
    Console.WriteLine(cleanString);
}

private static string ProcessHtmlTag(Match m)
{
    string tagName = m.Groups["tagName"].Value;
    string endTagPrefix = "";
    if(tagName.StartsWith("/"))
    {
endTagPrefix = "/";
tagName = tagName.Substring(1);
    }
    switch (tagName)
    {
case "b":
    tagName = "strong";
    break;
case "i":
    tagName = "em";
    break;
    }
    return "<" + endTagPrefix + tagName.ToLower() + ">";
}
    }
}

Первая часть примера выглядит точно так же, как и раньше, но вместо замены строки мы передаем ссылку на наш метод ProcessHtmlTag(). Как уже упоминалось, этот метод вызывается каждый раз, когда замена будет произведена, с матчем в качестве параметра. Это означает, что в нашем методе MatchEvaluator, у нас есть вся информация о матче, так что мы можем действовать соответственно. В этом случае мы используем эту возможность, чтобы сделать теги более семантическими, заменив тег bold (b) сильным тегом и тег italic (i) тегом с акцентом (em). Независимо от того, изменен тег или нет, мы превращаем его в Нижний регистр.

Использование параметра MatchEvaluator, очевидно, очень мощно, и это всего лишь простой пример того, что может быть достигнуто.

Резюме

Операции Поиска/Замены становятся очень полезными и даже больше того, когда вы используете регулярные выражения так что, когда вы пользуетесь параметром MatchEvaluator, возможности которого для манипуляций строками становятся почти безграничными.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!