Поделиться через


Подстановки в регулярных выражениях

Подстановки — это языковые элементы, которые распознаются только в шаблонах замены. Они используют шаблон регулярного выражения для определения всего текста или его части, предназначенной для замены совпадающего текста во входной строке. Шаблон замены может включать одну или несколько подстановок вместе с литеральными символами. Для перегруженных версий метода Regex.Replace , имеющих параметр replacement , и для метода Match.Result предоставляются шаблоны замены. Эти методы заменяют совпавший шаблон шаблоном, определенным параметром replacement .

Платформа .NET определяет элементы подстановки, перечисленные в следующей таблице.

Замена Description
$ number Включает в строку замены последнюю подстроку, соответствующую захватываемой группе, которая идентифицируется как number, где number — десятичное значение. Дополнительные сведения см. в разделе Подстановка нумерованной группы.
${ name } Включает в строку замены последнюю подстроку, соответствующую именованной группе, обозначаемой как (?<name> ) . Дополнительные сведения см. в разделе Подстановка именованной группы.
$$ Включает один литерал "$" в строку замены. Дополнительные сведения см. в разделе Подстановка символа "$".
$& Включает копию всего соответствия в строку замены. Дополнительные сведения см. в разделе Подстановка всего соответствия.
$` Включает весь текст входной строки до соответствия в строку замены. Дополнительные сведения см. в разделе Подстановка текста до соответствия.
$' Включает весь текст входной строки после соответствия в строку замены. Дополнительные сведения см. в разделе Подстановка текста после соответствия.
$+ Включает последнюю записанную группу в строку замены. Дополнительные сведения см. в разделе Подстановка последней записанной группы.
$_ Включает всю входную строку в строку замены. Дополнительные сведения см. в разделе Замена всей входной строки.

Элементы подстановки и шаблонов замены

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

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

Примечание.

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

Подстановка нумерованной группы

Языковой элемент $number включает последнюю подстроку, сопоставленную по группе записи number в строке замены, где number — это индекс группы записи. Например, шаблон замены $1 указывает, что совпадающая подстрока будет заменена первой группой записи. Дополнительные сведения о нумерованных группах записи см. в разделе Grouping Constructs.

Все цифры, указанные после $ , интерпретируются как относящиеся к группе number . Если это не соответствует вашим намерениям, можно вместо этого подставить именованную группу. Например, можно использовать строку замены ${1}1 вместо $11 , чтобы определить строку замены как значение первой записанной группы вместе с номером "1". Дополнительные сведения см. в разделе Подстановка именованной группы.

Группы записи, которым явно не назначены имена с помощью синтаксиса (?<name>) , нумеруются слева направо, начиная с единицы. Именованные группы также нумеруются слева направо, начиная с номера, превышающего индекс последней неименованной группы. Например, в регулярном выражении (\w)(?<digit>\d) индекс именованной группы digit — 2.

Если number не соответствует допустимой группе записи, определенной в шаблоне регулярного выражения, $number интерпретируется как последовательность литеральных символов, используемая для замены каждого соответствия.

В следующем примере подстановка $number используется для удаления символа валюты из десятичного значения. Она удаляет символы денежной единицы, найденные в начале или конце денежного значения, и распознает два наиболее распространенных десятичных разделителя ("." и ",").

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\p{Sc}*(\s?\d+[.,]?\d*)\p{Sc}*";
      string replacement = "$1";
      string input = "$16.32 12.19 £16.29 €18.29  €18,29";
      string result = Regex.Replace(input, pattern, replacement);
      Console.WriteLine(result);
   }
}
// The example displays the following output:
//       16.32 12.19 16.29 18.29  18,29
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\p{Sc}*(\s?\d+[.,]?\d*)\p{Sc}*"
        Dim replacement As String = "$1"
        Dim input As String = "$16.32 12.19 £16.29 €18.29  €18,29"
        Dim result As String = Regex.Replace(input, pattern, replacement)
        Console.WriteLine(result)
    End Sub
End Module
' The example displays the following output:
'       16.32 12.19 16.29 18.29  18,29

Шаблон регулярного выражения \p{Sc}*(\s?\d+[.,]?\d*)\p{Sc}* определяется, как показано в следующей таблице.

Расписание Description
\p{Sc}* Совпадение с нулем или более символами денежной единицы.
\s? Совпадение с нулем или одним символом пробела.
\d+ Совпадение с одной или несколькими десятичными цифрами.
[.,]? Совпадение с нулем или одной точкой либо запятой.
\d* Соответствует нулю или нескольким десятичным числам.
(\s?\d+[.,]?\d*) Совпадение с пробелом, за которым следует одна или несколько десятичных цифр, после которых идет ноль или одна точка либо запятая, а за ними — ноль или более десятичных цифр. Это первая группа записи. Так как шаблон замены имеет вид $1, вызов метода Regex.Replace заменяет всю совпадающую подстроку данной группой записи.

Подстановка именованной группы

Языковой элемент ${name} замещает последнюю подстроку, сопоставленную по группе записи name , где name — это имя группы записи, определенной в языковом элементе (?<name>) . Дополнительные сведения об именованных группах записи см. в разделе Grouping Constructs.

Если name не соответствует допустимой именованной группе записи, определенной в регулярном выражении, и состоит из цифр, то ${name} интерпретируется как нумерованная группа.

Если name не соответствует ни допустимой именованной группе записи, ни допустимой нумерованной группе записи, определенной в шаблоне регулярного выражения, ${name} интерпретируется как последовательность литеральных символов, используемая для замены каждого соответствия.

В следующем примере подстановка ${name} используется для удаления символа валюты из десятичного значения. Она удаляет символы денежной единицы, найденные в начале или конце денежного значения, и распознает два наиболее распространенных десятичных разделителя ("." и ",").

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\p{Sc}*(?<amount>\s?\d+[.,]?\d*)\p{Sc}*";
      string replacement = "${amount}";
      string input = "$16.32 12.19 £16.29 €18.29  €18,29";
      string result = Regex.Replace(input, pattern, replacement);
      Console.WriteLine(result);
   }
}
// The example displays the following output:
//       16.32 12.19 16.29 18.29  18,29
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\p{Sc}*(?<amount>\s?\d+[.,]?\d*)\p{Sc}*"
        Dim replacement As String = "${amount}"
        Dim input As String = "$16.32 12.19 £16.29 €18.29  €18,29"
        Dim result As String = Regex.Replace(input, pattern, replacement)
        Console.WriteLine(result)
    End Sub
End Module
' The example displays the following output:
'       16.32 12.19 16.29 18.29  18,29

Шаблон регулярного выражения \p{Sc}*(?<amount>\s?\d[.,]?\d*)\p{Sc}* определяется, как показано в следующей таблице.

Расписание Description
\p{Sc}* Совпадение с нулем или более символами денежной единицы.
\s? Совпадение с нулем или одним символом пробела.
\d+ Совпадение с одной или несколькими десятичными цифрами.
[.,]? Совпадение с нулем или одной точкой либо запятой.
\d* Соответствует нулю или нескольким десятичным числам.
(?<amount>\s?\d[.,]?\d*) Совпадение с пробелом, за которым следует одна или несколько десятичных цифр, после которых идет ноль или одна точка либо запятая, а за ними — ноль или более десятичных цифр. Это группа записи с именем amount. Так как шаблон замены имеет вид ${amount}, вызов метода Regex.Replace заменяет всю совпадающую подстроку данной группой записи.

Подстановка знака "$"

Подстановка $$ вставляет символ литерала "$"в строку замены.

В следующем примере объект NumberFormatInfo используется для определения символа валюты для текущего языка и региональных параметров и его размещения в строке валюты. Затем он динамически создает как шаблон регулярного выражения, так и шаблон замены. Если пример выполняется на компьютере, где в качестве языка и региональных параметров задано значение «Английский — США» (en-US), будет создан шаблон регулярного выражения \b(\d+)(\.(\d+))? и шаблон замены $$ $1$2. Шаблон замены замещает совпавший текст символом валюты и пробелом после первой и второй записанной группы.

using System;
using System.Globalization;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      // Define array of decimal values.
      string[] values= { "16.35", "19.72", "1234", "0.99"};
      // Determine whether currency precedes (True) or follows (False) number.
      bool precedes = NumberFormatInfo.CurrentInfo.CurrencyPositivePattern % 2 == 0;
      // Get decimal separator.
      string cSeparator = NumberFormatInfo.CurrentInfo.CurrencyDecimalSeparator;
      // Get currency symbol.
      string symbol = NumberFormatInfo.CurrentInfo.CurrencySymbol;
      // If symbol is a "$", add an extra "$".
      if (symbol == "$") symbol = "$$";

      // Define regular expression pattern and replacement string.
      string pattern = @"\b(\d+)(" + cSeparator + @"(\d+))?";
      string replacement = "$1$2";
      replacement = precedes ? symbol + " " + replacement : replacement + " " + symbol;
      foreach (string value in values)
         Console.WriteLine("{0} --> {1}", value, Regex.Replace(value, pattern, replacement));
   }
}
// The example displays the following output:
//       16.35 --> $ 16.35
//       19.72 --> $ 19.72
//       1234 --> $ 1234
//       0.99 --> $ 0.99
Imports System.Globalization
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        ' Define array of decimal values.
        Dim values() As String = {"16.35", "19.72", "1234", "0.99"}
        ' Determine whether currency precedes (True) or follows (False) number.
        Dim precedes As Boolean = (NumberFormatInfo.CurrentInfo.CurrencyPositivePattern Mod 2 = 0)
        ' Get decimal separator.
        Dim cSeparator As String = NumberFormatInfo.CurrentInfo.CurrencyDecimalSeparator
        ' Get currency symbol.
        Dim symbol As String = NumberFormatInfo.CurrentInfo.CurrencySymbol
        ' If symbol is a "$", add an extra "$".
        If symbol = "$" Then symbol = "$$"

        ' Define regular expression pattern and replacement string.
        Dim pattern As String = "\b(\d+)(" + cSeparator + "(\d+))?"
        Dim replacement As String = "$1$2"
        replacement = If(precedes, symbol + " " + replacement, replacement + " " + symbol)
        For Each value In values
            Console.WriteLine("{0} --> {1}", value, Regex.Replace(value, pattern, replacement))
        Next
    End Sub
End Module
' The example displays the following output:
'       16.35 --> $ 16.35
'       19.72 --> $ 19.72
'       1234 --> $ 1234
'       0.99 --> $ 0.99

Шаблон регулярного выражения \b(\d+)(\.(\d+))? определяется, как показано в следующей таблице.

Расписание Description
\b Начало соответствия в начале границы слова.
(\d+) Совпадение с одной или несколькими десятичными цифрами. Это первая группа записи.
\. Совпадение с точкой (десятичным разделителем).
(\d+) Совпадение с одной или несколькими десятичными цифрами. Это третья группа записи.
(\.(\d+))? Совпадение с нулем или одним вхождением точки, за которой следует одна или несколько десятичных цифр. Это вторая группа записи.

Подстановка всего соответствия

Подстановка $& включает все соответствие в строку замены. Часто она используется для добавления подстроки в начало или в конец совпадающей строки. Например, шаблон замены ($&) добавляет скобки в начало и в конец каждого соответствия. Если нет соответствия, подстановка $& не оказывает влияния.

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

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"^(\w+\s?)+$";
      string[] titles = { "A Tale of Two Cities",
                          "The Hound of the Baskervilles",
                          "The Protestant Ethic and the Spirit of Capitalism",
                          "The Origin of Species" };
      string replacement = "\"$&\"";
      foreach (string title in titles)
         Console.WriteLine(Regex.Replace(title, pattern, replacement));
   }
}
// The example displays the following output:
//       "A Tale of Two Cities"
//       "The Hound of the Baskervilles"
//       "The Protestant Ethic and the Spirit of Capitalism"
//       "The Origin of Species"
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "^(\w+\s?)+$"
        Dim titles() As String = {"A Tale of Two Cities", _
                                   "The Hound of the Baskervilles", _
                                   "The Protestant Ethic and the Spirit of Capitalism", _
                                   "The Origin of Species"}
        Dim replacement As String = """$&"""
        For Each title As String In titles
            Console.WriteLine(Regex.Replace(title, pattern, replacement))
        Next
    End Sub
End Module
' The example displays the following output:
'       "A Tale of Two Cities"
'       "The Hound of the Baskervilles"
'       "The Protestant Ethic and the Spirit of Capitalism"
'       "The Origin of Species"

Шаблон регулярного выражения ^(\w+\s?)+$ определяется, как показано в следующей таблице.

Расписание Description
^ Начало соответствия в начале входной строки.
(\w+\s?)+ Выделяет один или несколько раз шаблон из одного или нескольких словообразующих символов, за которыми следует ноль или один символ пробела.
$ Соответствует концу входной строки.

Шаблон замены "$&" добавляет литеральные кавычки в начало и в конец каждого соответствия.

Подстановка текста до соответствия

Подстановка $` заменяет совпадающую строку всей входной строкой до соответствия. То есть она дублирует входную строку вплоть до соответствия, удаляя совпадающий текст. Любой текст, следующий за совпадающим текстом, не изменяется в результирующей строке. Если во входной строке несколько соответствий, текст замены выводится из исходной входной строки, а не из строки, в которой текст был заменен более ранними совпадениями. (Пример содержит иллюстрацию.) Если совпадения $` нет, подстановка не действует.

В следующем примере шаблон регулярного выражения \d+ используется для сопоставления последовательности из одной или нескольких цифр десятичного числа во входной строке. Строка замены $` заменяет эти цифры текстом, который предшествует совпадению.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "aa1bb2cc3dd4ee5";
      string pattern = @"\d+";
      string substitution = "$`";
      Console.WriteLine("Matches:");
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index);

      Console.WriteLine("Input string:  {0}", input);
      Console.WriteLine("Output string: " +
                        Regex.Replace(input, pattern, substitution));
   }
}
// The example displays the following output:
//    Matches:
//       1 at position 2
//       2 at position 5
//       3 at position 8
//       4 at position 11
//       5 at position 14
//    Input string:  aa1bb2cc3dd4ee5
//    Output string: aaaabbaa1bbccaa1bb2ccddaa1bb2cc3ddeeaa1bb2cc3dd4ee
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim input As String = "aa1bb2cc3dd4ee5"
        Dim pattern As String = "\d+"
        Dim substitution As String = "$`"
        Console.WriteLine("Matches:")
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
        Next
        Console.WriteLine("Input string:  {0}", input)
        Console.WriteLine("Output string: " + _
                          Regex.Replace(input, pattern, substitution))
    End Sub
End Module
' The example displays the following output:
'    Matches:
'       1 at position 2
'       2 at position 5
'       3 at position 8
'       4 at position 11
'       5 at position 14
'    Input string:  aa1bb2cc3dd4ee5
'    Output string: aaaabbaa1bbccaa1bb2ccddaa1bb2cc3ddeeaa1bb2cc3dd4ee

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

Поиск совпадений (Match) Position Строка до соответствия Результирующая строка
1 2 aa aaaabb2cc3dd4ee5
2 5 aa1bb aaaabbaa1bbcc3dd4ee5
3 8 aa1bb2cc aaaabbaa1bbccaa1bb2ccdd4ee5
4 11 aa1bb2cc3dd aaaabbaa1bbccaa1bb2ccddaa1bb2cc3ddee5
5 14 aa1bb2cc3dd4ee aaaabbaa1bbccaa1bb2ccddaa1bb2cc3ddeeaa1bb2cc3dd4ee

Подстановка текста после соответствия

Подстановка $' заменяет совпадающую строку всей входной строкой после соответствия. То есть входная строка после соответствия дублируется с удалением совпадающего текста. Любой текст, который предшествует совпадающему тексту, не изменяется в результирующей строке. Если нет соответствия, подстановка $' не оказывает влияния.

В следующем примере шаблон регулярного выражения \d+ используется для сопоставления последовательности из одной или нескольких цифр десятичного числа во входной строке. Строка замены $' заменяет эти цифры текстом, который следует за соответствием.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "aa1bb2cc3dd4ee5";
      string pattern = @"\d+";
      string substitution = "$'";
      Console.WriteLine("Matches:");
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index);
      Console.WriteLine("Input string:  {0}", input);
      Console.WriteLine("Output string: " +
                        Regex.Replace(input, pattern, substitution));
   }
}
// The example displays the following output:
//    Matches:
//       1 at position 2
//       2 at position 5
//       3 at position 8
//       4 at position 11
//       5 at position 14
//    Input string:  aa1bb2cc3dd4ee5
//    Output string: aabb2cc3dd4ee5bbcc3dd4ee5ccdd4ee5ddee5ee
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim input As String = "aa1bb2cc3dd4ee5"
        Dim pattern As String = "\d+"
        Dim substitution As String = "$'"
        Console.WriteLine("Matches:")
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
        Next
        Console.WriteLine("Input string:  {0}", input)
        Console.WriteLine("Output string: " + _
                          Regex.Replace(input, pattern, substitution))
    End Sub
End Module
' The example displays the following output:
'    Matches:
'       1 at position 2
'       2 at position 5
'       3 at position 8
'       4 at position 11
'       5 at position 14
'    Input string:  aa1bb2cc3dd4ee5
'    Output string: aabb2cc3dd4ee5bbcc3dd4ee5ccdd4ee5ddee5ee

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

Поиск совпадений (Match) Position Строка после соответствия Результирующая строка
1 2 bb2cc3dd4ee5 aabb2cc3dd4ee5bb2cc3dd4ee5
2 5 cc3dd4ee5 aabb2cc3dd4ee5bbcc3dd4ee5cc3dd4ee5
3 8 dd4ee5 aabb2cc3dd4ee5bbcc3dd4ee5ccdd4ee5dd4ee5
4 11 ee5 aabb2cc3dd4ee5bbcc3dd4ee5ccdd4ee5ddee5ee5
5 14 String.Empty aabb2cc3dd4ee5bbcc3dd4ee5ccdd4ee5ddee5ee

Подстановка последней записанной группы

Подстановка $+ заменяет совпадающую строку всей последней группой записи. Если группы записи отсутствуют или значение последней захваченной группы равно String.Empty, подстановка $+ не оказывает влияния.

В следующем примере в строке определяются повторяющиеся слова и используется подстановка $+ для их замены одним вхождением слова. Параметр RegexOptions.IgnoreCase позволяет убедиться, что слова, отличающиеся регистром, но идентичные во всем остальном, считаются дубликатами.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(\w+)\s\1\b";
      string substitution = "$+";
      string input = "The the dog jumped over the fence fence.";
      Console.WriteLine(Regex.Replace(input, pattern, substitution,
                        RegexOptions.IgnoreCase));
   }
}
// The example displays the following output:
//      The dog jumped over the fence.
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b(\w+)\s\1\b"
        Dim substitution As String = "$+"
        Dim input As String = "The the dog jumped over the fence fence."
        Console.WriteLine(Regex.Replace(input, pattern, substitution, _
                                        RegexOptions.IgnoreCase))
    End Sub
End Module
' The example displays the following output:
'      The dog jumped over the fence.

Шаблон регулярного выражения \b(\w+)\s\1\b определяется, как показано в следующей таблице.

Расписание Description
\b Совпадение должно начинаться на границе слова.
(\w+) Совпадение с одним или несколькими символами слова. Это первая группа записи.
\s Соответствует пробелу.
\1 Соответствует первой группе записи.
\b Совпадение должно заканчиваться на границе слова.

Замена всей входной строки

Подстановка $_ заменяет совпадающую строку всей входной строкой. То есть совпадающий текст удаляется и заменяется всей строкой, включая совпадающий текст.

В следующем примере сопоставляется одна или несколько цифр десятичного числа во входной строке. При этом используется подстановка $_ для их замены входной строкой.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "ABC123DEF456";
      string pattern = @"\d+";
      string substitution = "$_";
      Console.WriteLine("Original string:          {0}", input);
      Console.WriteLine("String with substitution: {0}",
                        Regex.Replace(input, pattern, substitution));
   }
}
// The example displays the following output:
//       Original string:          ABC123DEF456
//       String with substitution: ABCABC123DEF456DEFABC123DEF456
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim input As String = "ABC123DEF456"
        Dim pattern As String = "\d+"
        Dim substitution As String = "$_"
        Console.WriteLine("Original string:          {0}", input)
        Console.WriteLine("String with substitution: {0}", _
                          Regex.Replace(input, pattern, substitution))
    End Sub
End Module
' The example displays the following output:
'       Original string:          ABC123DEF456
'       String with substitution: ABCABC123DEF456DEFABC123DEF456

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

Поиск совпадений (Match) Position Поиск совпадений (Match) Результирующая строка
1 3 123 ABCABC123DEF456DEF456
2 5 456 ABCABC123DEF456DEFABC123DEF456

См. также