Конструкции изменения

Конструкции изменения модифицируют регулярное выражение, чтобы включить сопоставление по принципу "либо-либо" или условное сопоставление. Платформа .NET Framework поддерживает три конструкции чередования:

  • Сопоставление шаблонов с помощью оператора |

  • Условное сопоставление с (? (выражение) yes|no)

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

Сопоставление шаблонов с помощью оператора |

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

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

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           
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           

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

Шаблон

Описание

\b

Начало на границе слова.

gr

Выделить символы "gr".

(a|e)

Соответствует "a" или "e".

y\b

Выделяет "y" на границе слова.

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

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
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

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

Шаблон

Описание

\b

Начало на границе слова.

(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})

Совпадает со следующими символами: двумя десятичными цифрами с последующим дефисом, за которым идут семь десятичных цифр; или тремя десятичными цифрами, дефисом, двумя десятичными цифрами, еще одним дефисом и четырьмя десятичными цифрами.

\d

Совпадение должно заканчиваться на границе слова.

К началу

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

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

(?(выражение)да|нет)

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

(?(?=выражение)да|нет)

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

ПримечаниеПримечание

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

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

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
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

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

Шаблон

Описание

\b

Начало на границе слова.

(?(\d{2}-)

Определите, состоят ли следующие три символа из двух цифр, за которыми следуют дефис.

\d{2}-\d{7}

Если предыдущий шаблон совпадает, то сравниваются две цифры, за которыми следует дефис и семь цифр.

\d{3}-\d{2}-\d{4}

Если предыдущий шаблон не соответствует, то сравниваются три десятичных цифры, дефис, две десятичных цифры, другой дефис, и четыре десятичных цифры.

\b

Соответствует границе слова.

К началу

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

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

(?(имя)да|нет)

или

(?(число)да|нет)

где имя — это имя, а номер — это номер группы записи, да — это выражение для сравнения, если для имени или номера имеется совпадение, а нет — это необязательное выражение для сравнения, если совпадения нет.

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

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

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
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

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

Шаблон

Описание

\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.

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
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

К началу

См. также

Основные понятия

Элементы языка регулярных выражений