Конструкции изменения в регулярных выражениях

Конструкции изменения модифицируют регулярное выражение, включая сопоставление по принципу «либо/или» или условное сопоставление. Платформа .NET поддерживает три указанные далее конструкции изменения.

Сопоставление шаблонов с |

Вертикальную черту (|) можно использовать для сопоставления с любым набором шаблонов, в котором шаблоны разделяются с помощью символа |.

Как и класс положительных символов, символ | можно использовать для сопоставления с любым количеством отдельных символов. В следующем примере используется класс положительных символов и сопоставление с шаблоном либо/или с символом | для обнаружения в строке всех вхождений слов gray или grey. В этом случае символ | создает регулярное выражение, которое является более подробным.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      // Regular expression using character class.
      string pattern1 = @"\bgr[ae]y\b";
      // Regular expression using either/or.
      string pattern2 = @"\bgr(a|e)y\b";

      string input = "The gray wolf blended in among the grey rocks.";
      foreach (Match match in Regex.Matches(input, pattern1))
         Console.WriteLine("'{0}' found at position {1}",
                           match.Value, match.Index);
      Console.WriteLine();
      foreach (Match match in Regex.Matches(input, pattern2))
         Console.WriteLine("'{0}' found at position {1}",
                           match.Value, match.Index);
   }
}
// The example displays the following output:
//       'gray' found at position 4
//       'grey' found at position 35
//
//       'gray' found at position 4
//       'grey' found at position 35
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        ' Regular expression using character class.
        Dim pattern1 As String = "\bgr[ae]y\b"
        ' Regular expression using either/or.
        Dim pattern2 As String = "\bgr(a|e)y\b"

        Dim input As String = "The gray wolf blended in among the grey rocks."
        For Each match As Match In Regex.Matches(input, pattern1)
            Console.WriteLine("'{0}' found at position {1}", _
                              match.Value, match.Index)
        Next
        Console.WriteLine()
        For Each match As Match In Regex.Matches(input, pattern2)
            Console.WriteLine("'{0}' found at position {1}", _
                              match.Value, match.Index)
        Next
    End Sub
End Module
' The example displays the following output:
'       'gray' found at position 4
'       'grey' found at position 35
'       
'       'gray' found at position 4
'       'grey' found at position 35           

Возможные интерпретации регулярного выражения, использующего символ |, \bgr(a|e)y\b, показаны в следующей таблице:

Расписание Description
\b Начало на границе слова.
gr Соответствует символам gr.
(a|e) Соответствует букве "a" или "e".
y\b Соответствует символу у на границе слова.

С помощью символа | также можно выполнить сопоставление "или/либо" с несколькими символами или частями выражения, которые могут включать любую комбинацию символьных литералов и элементов языка регулярных выражений. (Класс символов не предоставляет эту функциональность.) В следующем примере символ используется | для извлечения номера социального страхования США (SSN), который является 9-цифрным номером с форматом ddd--d d, или номером идентификации работодателя США (EIN), который является 9-цифрным номером с форматом -d.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b";
      string input = "01-9999999 020-333333 777-88-9999";
      Console.WriteLine("Matches for {0}:", pattern);
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index);
   }
}
// The example displays the following output:
//       Matches for \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
//          01-9999999 at position 0
//          777-88-9999 at position 22
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b"
        Dim input As String = "01-9999999 020-333333 777-88-9999"
        Console.WriteLine("Matches for {0}:", pattern)
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
        Next
    End Sub
End Module
' The example displays the following output:
'       Matches for \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
'          01-9999999 at position 0
'          777-88-9999 at position 22

Возможные интерпретации регулярного выражения \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b показаны в следующей таблице:

Расписание Description
\b Начало на границе слова.
(\d{2}-\d{7}|\d{3}-\d{2}-\d{4}) Сопоставьте любые из следующих значений: два десятичных знака, за которыми следует дефис и еще семь десятичных знаков; или последовательность из трех десятичных знаков, дефиса, двух десятичных знаков, еще одного дефиса и четырех десятичных знаков.
\b Совпадение должно заканчиваться на границе слова.

Условное сопоставление с выражением

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

(?(выражение "Да"))

or

(?(expression)yes|no)

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

(?(?=expression)yes|no)

Где (?=expression) — это проверочное утверждение нулевой ширины. (Дополнительные сведения см. в разделе Сгруппирование конструкций.) Так как обработчик регулярных выражений интерпретирует выражение как привязку (утверждение нулевой ширины), выражение должно быть утверждением нулевой ширины (дополнительные сведения см. в разделе "Привязки") или вложенное выражение, которое также содержится в да. В противном случае шаблон yes сопоставить невозможно.

Примечание.

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

В следующем примере представлен вариант примера, который отображается в разделе "Сопоставление шаблонов" с | . Условное сопоставление используется, чтобы определить, являются ли первые три символа после границы слова двумя цифрами и дефисом. Если да, предпринимается попытка сопоставить Идентификационный номер работодателя США (EIN). Если нет, предпринимается попытка сопоставить Номер социального страхования США (SSN).

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b";
      string input = "01-9999999 020-333333 777-88-9999";
      Console.WriteLine("Matches for {0}:", pattern);
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index);
   }
}
// The example displays the following output:
//       Matches for \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
//          01-9999999 at position 0
//          777-88-9999 at position 22
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b"
        Dim input As String = "01-9999999 020-333333 777-88-9999"
        Console.WriteLine("Matches for {0}:", pattern)
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
        Next
    End Sub
End Module
' The example displays the following output:
'       Matches for \b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
'          01-9999999 at position 0
'          777-88-9999 at position 22

Возможные интерпретации шаблона регулярного выражения \b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b показаны в следующей таблице:

Расписание Description
\b Начало на границе слова.
(?(\d{2}-) Определите, состоят ли следующие три символа из двух цифр, за которыми следуют дефис.
\d{2}-\d{7} Если предыдущий шаблон сопоставлен, сопоставьте две цифры с дефисом, за которыми следуют еще семь цифр.
\d{3}-\d{2}-\d{4} Если предыдущий шаблон не сопоставлен, сопоставьте три цифры, дефис, две цифры, еще один дефис и еще четыре цифры.
\b Соответствует границе слова.

Условное сопоставление на основе действительной захватываемой группы.

Этот элемент языка пытается сопоставить один из двух шаблонов, в зависимости от того, соответствует ли он указанной группе записи. Синтаксис:

(?(имя)да)

or

(?(name)yes|no)

or

(?(число)да)

or

(?(number)да|нет)

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

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

В следующем примере представлен вариант примера, который отображается в разделе "Сопоставление шаблонов" с | . В нем используется захватываемая группа с именем n2 , которая состоит из двух цифр и дефиса. Конструкция изменения проверяет, сопоставлена ли эта группа захвата в строке ввода. Если да, конструкция изменения пытается сопоставить последние семь цифр девятизначного Идентификационный номер работодателя США (EIN). В противном случае она пытается сопоставить девятизначный Номер социального страхования США (SSN).

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(?<n2>\d{2}-)?(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b";
      string input = "01-9999999 020-333333 777-88-9999";
      Console.WriteLine("Matches for {0}:", pattern);
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index);
   }
}
// The example displays the following output:
//       Matches for \b(?<n2>\d{2}-)?(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b:
//          01-9999999 at position 0
//          777-88-9999 at position 22
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b(?<n2>\d{2}-)?(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b"
        Dim input As String = "01-9999999 020-333333 777-88-9999"
        Console.WriteLine("Matches for {0}:", pattern)
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
        Next
    End Sub
End Module

Возможные интерпретации шаблона регулярного выражения \b(?<n2>\d{2}-)?(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b показаны в следующей таблице:

Расписание Description
\b Начало на границе слова.
(?<n2>\d{2}-)? Сопоставьте нулевое или единичное вхождение двух цифр с дефисом. Установка для группы имени n2.
(?(n2) Проверка наличия сопоставления n2 во входной строке.
\d{7} Если есть сопоставление n2 , сопоставляются семь десятичных цифр.
|\d{3}-\d{2}-\d{4} Если сопоставления нет n2 , сопоставляются три десятичных цифры, дефис, две десятичных цифры, еще один дефис и четыре десятичных цифры.
\b Соответствует границе слова.

В следующем примере показана вариация этого примера, в котором вместо именованной группы используется нумерованная. Шаблон регулярного выражения выглядит следующим образом: \b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b";
      string input = "01-9999999 020-333333 777-88-9999";
      Console.WriteLine("Matches for {0}:", pattern);
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index);
   }
}
// The example display the following output:
//       Matches for \b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b:
//          01-9999999 at position 0
//          777-88-9999 at position 22
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b"
        Dim input As String = "01-9999999 020-333333 777-88-9999"
        Console.WriteLine("Matches for {0}:", pattern)
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
        Next
    End Sub
End Module
' The example displays the following output:
'       Matches for \b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b:
'          01-9999999 at position 0
'          777-88-9999 at position 22

См. также