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

По умолчанию сравнение входной строку с любыми литеральными символами в шаблоне регулярного выражения чувствительно к регистру, пробелы в шаблоне регулярного выражения интерпретируется как литеральные знаки пробелов, и группы захвата в регулярном выражении получают имена неявно и явно. Можно изменить эти и несколько других аспектов поведения по умолчанию регулярного выражения, указав параметры регулярных выражений. Эти параметры, перечисленные в следующей таблице, могут быть включены встроено как часть шаблона регулярного выражения или могут быть задано для конструктора класса System.Text.RegularExpressions.Regex или статический метода сопоставления шаблона в качестве значения перечисления System.Text.RegularExpressions.RegexOptions.

Член RegexOption

Встроенный знак

Эффект

None

Недоступно

Использовать поведение по умолчанию. Дополнительные сведения см. в разделе Параметры по умолчанию.

IgnoreCase

i

Использовать соответствие без учета регистра. Дополнительные сведения см. в разделе Сопоставление, не учитывающее регистр.

Multiline

m

Используется многостроковый режим, где ^ и $ соответствуют началу каждой строки (вместо начала и конца входной строки). Дополнительные сведения содержатся в разделе Многострочный режим.

Singleline

s

Используйте однострочный режим, где точка (.) соответствует каждому символу (вместо каждого символа кроме \n). Дополнительные сведения см. в разделе Однострочный режим.

ExplicitCapture

n

Не захватывать неименованные группы. Единственные допустимые записи являются явно поименованными или пронумерованными группами в форме (?<имя> подвыражение). Дополнительные сведения содержатся в разделе Только явные захваты.

Compiled

Недоступно

Компилировать регулярное выражение в сборку. Дополнительные сведения содержатся в разделе Компилированные регулярные выражения.

IgnorePatternWhitespace

x

Исключить не преобразованные в escape-последовательность пробелы из шаблона и включить комментарии после знака номера (#). Дополнительные сведения содержатся в разделе Игнорирование пробелов.

RightToLeft

Недоступно

Изменить направление поиска. Поиск происходит справа налево вместо поиска слева направо. Дополнительные сведения содержатся в разделе Режим справа налево.

ECMAScript

Недоступно

Включает ECMAScript-совместимое поведение для выражения. Дополнительные сведения содержатся в разделе Поведение сопоставления ECMAScript.

CultureInvariant

Недоступно

Игнорировать культурные различия в языке. Дополнительные сведения см. в разделе Выполнение операций без учета языка и региональных параметров.

Задание параметров

Можно указать параметры для регулярных выражений одним из трех способов:

  • В параметре options конструктор класса System.Text.RegularExpressions.Regex или статический (Shared в Visual Basic) метод соответствия шаблону, например Regex.Regex(String, RegexOptions) или Regex.Match(String, String, RegexOptions). Параметр options является побитовой комбинацией ИЛИ перечисленных значений System.Text.RegularExpressions.RegexOptions.

    Ниже приведен пример. Он использует параметр options метода Regex.Match(String, String, RegexOptions) для включения сопоставления без учета регистра и игнорирования пробелов шаблона при идентификации слов, начинающиеся с буквы "d".

    Dim pattern As String = "d \w+ \s"
    Dim input As String = "Dogs are decidedly good pets."
    Dim options As RegexOptions = RegexOptions.IgnoreCase Or RegexOptions.IgnorePatternWhitespace
    
    For Each match As Match In Regex.Matches(input, pattern, options)
       Console.WriteLine("'{0}' found at index {1}.", match.Value, match.Index)
    Next
    ' The example displays the following output:
    '    'Dogs ' found at index 0.
    '    'decidedly ' found at index 9.      
    
    string pattern = @"d \w+ \s";
    string input = "Dogs are decidedly good pets.";
    RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace;
    
    foreach (Match match in Regex.Matches(input, pattern, options))
       Console.WriteLine("'{0}// found at index {1}.", match.Value, match.Index);
    // The example displays the following output:
    //    'Dogs // found at index 0.
    //    'decidedly // found at index 9.      
    
  • Применяя встроенные параметры в шаблон регулярного выражения с помощью синтаксиса (?imnsx-imnsx). Параметр применяется к шаблону из точки, определенной параметром, либо до конца шаблона, либо до точки, с которой параметр не определен другим встроенным параметром. Дополнительные сведения см. в разделе Другие конструкции.

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

    Dim pattern As String = "\b(?ix) d \w+ \s"
    Dim input As String = "Dogs are decidedly good pets."
    
    For Each match As Match In Regex.Matches(input, pattern)
       Console.WriteLine("'{0}' found at index {1}.", match.Value, match.Index)
    Next
    ' The example displays the following output:
    '    'Dogs ' found at index 0.
    '    'decidedly ' found at index 9.      
    
    string pattern = @"(?ix) d \w+ \s";
    string input = "Dogs are decidedly good pets.";
    
    foreach (Match match in Regex.Matches(input, pattern))
       Console.WriteLine("'{0}// found at index {1}.", match.Value, match.Index);
    // The example displays the following output:
    //    'Dogs // found at index 0.
    //    'decidedly // found at index 9.      
    
  • Применяя встроенные параметры в определенную конструкцию группировки в шаблон регулярного выражения с синтаксисом (?imnsx-imnsx:подвыражение). Отсутствие знака перед набором параметров включает набор, знак минус перед набором параметров отключает их. (? является фиксированной частью синтаксической конструкции языка, необходимой, независимо от того, были ли параметры включены или отключены). Параметр применяется только к этой группе. Дополнительные сведения см. в разделе Конструкции группирования.

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

    Dim pattern As String = "\b(?ix: d \w+)\s"
    Dim input As String = "Dogs are decidedly good pets."
    
    For Each match As Match In Regex.Matches(input, pattern)
       Console.WriteLine("'{0}' found at index {1}.", match.Value, match.Index)
    Next
    ' The example displays the following output:
    '    'Dogs ' found at index 0.
    '    'decidedly ' found at index 9.      
    
    string pattern = @"\b(?ix: d \w+)\s";
    string input = "Dogs are decidedly good pets.";
    
    foreach (Match match in Regex.Matches(input, pattern))
       Console.WriteLine("'{0}// found at index {1}.", match.Value, match.Index);
    // The example displays the following output:
    //    'Dogs // found at index 0.
    //    'decidedly // found at index 9.      
    

Если параметры задаются встроено, знак минус (-) перед параметром или набором параметров отключает эти параметры. Например встроенная конструкция (?ix-ms) включает параметры RegexOptions.IgnoreCase и RegexOptions.IgnorePatternWhitespace и отключает параметры RegexOptions.Multiline и RegexOptions.Singleline. По умолчанию все параметры регулярного выражения отключены.

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

Если параметры регулярного выражения, указанные в параметре options конструктора или вызова метода противоречат указанным встроено параметрам в шаблоне регулярного выражения, используются встроенные параметры.

Можно задать следующие пять параметров регулярного выражения и с помощью параметра параметров, и встроенного:

Можно задать следующие пять параметров регулярного выражения с помощью параметра options, но нельзя задать встроено:

Определение параметров

Чтобы определить, какие параметры были предоставлены для объекта Regex , когда он был создан путем извлечения значения свойства только для чтения Regex.Options. Это свойство особенно полезно для определения параметров, которые определены для компилируемого регулярного выражения, созданного методом Regex.CompileToAssembly.

Чтобы проверить наличие любого параметра кроме RegexOptions.Noneвыполните операцию И со значением свойства Regex.Options и значением RegexOptions, в котором заинтересованы. Затем проверьте, равен ли результат этому значению RegexOptions. Следующий пример проверяет, задан ли параметр RegexOptions.IgnoreCase.

If (rgx.Options And RegexOptions.IgnoreCase) = RegexOptions.IgnoreCase Then
   Console.WriteLine("Case-insensitive pattern comparison.")
Else
   Console.WriteLine("Case-sensitive pattern comparison.")
End If   
if ((rgx.Options & RegexOptions.IgnoreCase) == RegexOptions.IgnoreCase)
   Console.WriteLine("Case-insensitive pattern comparison.");
else
   Console.WriteLine("Case-sensitive pattern comparison.");

Чтобы проверить RegexOptions.None, определите, равно ли значение свойства Regex.Options RegexOptions.None, как показано в следующем примере.

If rgx.Options = RegexOptions.None Then
   Console.WriteLine("No options have been set.")
End If
if (rgx.Options == RegexOptions.None)
   Console.WriteLine("No options have been set.");

В следующих разделах перечислены параметры, поддерживаемые регулярными выражениями платформы .NET Framework.

Параметры по умолчанию

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

  • Шаблон интерпретируется как каноническое регулярное выражение, а не ECMAScript.

  • Шаблон регулярного выражения сопоставлен во входной строке, слева направо.

  • Сравнения выполняется с учетом регистра.

  • Элементы языка ^ и $ соответствует начало и конец входной строки.

  • Элемент языка . соответствует любому знаку, кроме \n.

  • Любой пробел в шаблон регулярного выражения, интерпретируется как пробел-литерал.

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

  • Группы захвата в шаблоне регулярного выражения являются неявными, а также явными.

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

Параметр RegexOptions.None не имеет встроенного эквивалента.Когда параметры регулярных выражений применены встроено, поведение по умолчанию восстанавливается на основе параметра, отключая определенный параметр.Например (?i) включает сравнение без учета регистра и (?-i) восстанавливает сравнение с учетом регистра по умолчанию.

Поскольку параметр RegexOptions.None представляет поведение по умолчанию обработчика регулярных выражений, он редко явно указывается в вызове метода. Вместо этого вызывается конструктор или статический метод соответствия шаблону без параметра options.

К началу

Соответствие без учета регистра

Параметр IgnoreCase или параметр встроенный i обеспечивает соответствие без учета регистра. По умолчанию используются правила регистра текущего языка и региональных параметров.

В следующем примере определяется шаблон регулярного выражения \bthe\w*\b, который соответствует всем словам, начинающиеся с "the". Поскольку первый вызов метода Match использует сравнение с учетом регистра по умолчанию, результат показывает, что строка "The", начинающая предложение, не сопоставлена. Сопоставляется при вызове метода Match с параметрами установленными на IgnoreCase.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "\bthe\w*\b"
      Dim input As String = "The man then told them about that event."
      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index)
      Next
      Console.WriteLine()
      For Each match As Match In Regex.Matches(input, pattern, _
                                               RegexOptions.IgnoreCase)
         Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index)
      Next
   End Sub
End Module
' The example displays the following output:
'       Found then at index 8.
'       Found them at index 18.
'       
'       Found The at index 0.
'       Found then at index 8.
'       Found them at index 18.
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\bthe\w*\b";
      string input = "The man then told them about that event.";
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index);

      Console.WriteLine();
      foreach (Match match in Regex.Matches(input, pattern, 
                                            RegexOptions.IgnoreCase))
         Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index);
   }
}
// The example displays the following output:
//       Found then at index 8.
//       Found them at index 18.
//       
//       Found The at index 0.
//       Found then at index 8.
//       Found them at index 18.

В следующем примере изменяется шаблон регулярного выражения из предыдущего примера для использования встроенных параметров вместо параметра options для предоставления сравнение без учета регистра. Первый шаблон определяет параметр без учета регистра в конструкции группировки, который применяется только к букве "t" в строке "the". Поскольку конструкция параметра происходит в начале шаблона, второй шаблон применяет параметр без учета регистра ко всему регулярное выражение.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "\b(?i:t)he\w*\b"
      Dim input As String = "The man then told them about that event."
      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index)
      Next
      Console.WriteLine()
      pattern = "(?i)\bthe\w*\b"
      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index)
      Next
   End Sub
End Module
' The example displays the following output:
'       Found The at index 0.
'       Found then at index 8.
'       Found them at index 18.
'       
'       Found The at index 0.
'       Found then at index 8.
'       Found them at index 18.
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(?i:t)he\w*\b";
      string input = "The man then told them about that event.";
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index);

      Console.WriteLine();
      pattern = @"(?i)\bthe\w*\b";
      foreach (Match match in Regex.Matches(input, pattern, 
                                            RegexOptions.IgnoreCase))
         Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index);
   }
}
// The example displays the following output:
//       Found The at index 0.
//       Found then at index 8.
//       Found them at index 18.
//       
//       Found The at index 0.
//       Found then at index 8.
//       Found them at index 18.

К началу

Многострочный режим

Параметр RegexOptions.Multiline или параметр встроенный m позволяет обработчику регулярных выражений обрабатывать входную строку, состоящей из нескольких строк. Изменяет интерпретацию элементов языка ^ и $ таким образом, чтобы они соответствовали началу и концу строки вместо начала и конца входной строки.

По умолчанию $ соответствует только концу входной строки. Если указать параметр RegexOptions.Multiline, он соответствует либо символу (\n) либо концу входной строки. Однако он не, соответствует сочетанию символов возврата каретки/перевода строки. Для успешного сопоставления используйте подвыражение \r?$ вместо просто $.

Следующий пример извлекает имена игроков в боулинг и очки и добавляет их в коллекцию SortedList<TKey, TValue>, сортирующую их в порядке убывания. Дважды вызывается метод Matches. В первом вызове метода регулярное выражения является ^(\w+)\s(\d+)$ и параметры не заданы. Как показывает выходные данные, поскольку обработчик регулярных выражений не может сопоставить шаблон ввода с начало и конец входной строки, совпадения не найдены. Во втором вызове метода регулярное выражения меняется на ^(\w+)\s(\d+)\r?$ и параметры устанавливаются на RegexOptions.Multiline. Как результат показывает, успешно совпадают имена и показатели, и показатели отображаются в порядке убывания.

Imports System.Collections.Generic
Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim scores As New SortedList(Of Integer, String)(New DescendingComparer(Of Integer)())

      Dim input As String = "Joe 164" + vbCrLf + _
                            "Sam 208" + vbCrLf + _
                            "Allison 211" + vbCrLf + _
                            "Gwen 171" + vbCrLf
      Dim pattern As String = "^(\w+)\s(\d+)$"
      Dim matched As Boolean = False

      Console.WriteLine("Without Multiline option:")
      For Each match As Match In Regex.Matches(input, pattern)
         scores.Add(CInt(match.Groups(2).Value), match.Groups(1).Value)
         matched = True
      Next
      If Not matched Then Console.WriteLine("   No matches.")
      Console.WriteLine()

      ' Redefine pattern to handle multiple lines.
      pattern = "^(\w+)\s(\d+)\r*$"
      Console.WriteLine("With multiline option:")
      For Each match As Match In Regex.Matches(input, pattern, RegexOptions.Multiline)
         scores.Add(CInt(match.Groups(2).Value), match.Groups(1).Value)
      Next
      ' List scores in descending order. 
      For Each score As KeyValuePair(Of Integer, String) In scores
         Console.WriteLine("{0}: {1}", score.Value, score.Key)
      Next
   End Sub
End Module

Public Class DescendingComparer(Of T) : Implements IComparer(Of T)
   Public Function Compare(x As T, y As T) As Integer _
          Implements IComparer(Of T).Compare
      Return Comparer(Of T).Default.Compare(x, y) * -1       
   End Function
End Class
' The example displays the following output:
'    Without Multiline option:
'       No matches.
'    
'    With multiline option:
'    Allison: 211
'    Sam: 208
'    Gwen: 171
'    Joe: 164
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      SortedList<int, string> scores = new SortedList<int, string>(new DescendingComparer<int>());

      string input = "Joe 164\n" + 
                     "Sam 208\n" + 
                     "Allison 211\n" + 
                     "Gwen 171\n"; 
      string pattern = @"^(\w+)\s(\d+)$";
      bool matched = false;

      Console.WriteLine("Without Multiline option:");
      foreach (Match match in Regex.Matches(input, pattern))
      {
         scores.Add(Int32.Parse(match.Groups[2].Value), (string) match.Groups[1].Value);
         matched = true;
      }
      if (! matched)
         Console.WriteLine("   No matches.");
      Console.WriteLine();

      // Redefine pattern to handle multiple lines.
      pattern = @"^(\w+)\s(\d+)\r*$";
      Console.WriteLine("With multiline option:");
      foreach (Match match in Regex.Matches(input, pattern, RegexOptions.Multiline))
         scores.Add(Int32.Parse(match.Groups[2].Value), (string) match.Groups[1].Value);

      // List scores in descending order. 
      foreach (KeyValuePair<int, string> score in scores)
         Console.WriteLine("{0}: {1}", score.Value, score.Key);
   }
}

public class DescendingComparer<T> : IComparer<T>
{
   public int Compare(T x, T y)
   {
      return Comparer<T>.Default.Compare(x, y) * -1;       
   }
}
// The example displays the following output:
//   Without Multiline option:
//      No matches.
//   
//   With multiline option:
//   Allison: 211
//   Sam: 208
//   Gwen: 171
//   Joe: 164

Возможные интерпретации шаблона регулярного выражения ^(\w+)\s(\d+)\r*$ определены в следующей таблице.

Шаблон

Описание

^

Начинается с начала строки.

(\w+)

Совпадение с одним или несколькими символами слова. Это первая группа записи.

\s

Соответствует пробелу.

(\d+)

Совпадение с одной или несколькими десятичными цифрами. Это вторая группа записи.

\r?

Соответствует нолю или одному символу возврата каретки.

$

Конечная точка на конце линии.

Следующий пример эквивалентен предыдущему, за исключением того, что он использует параметр встроенный (?m) для установки многострочного параметра.

Imports System.Collections.Generic
Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim scores As New SortedList(Of Integer, String)(New DescendingComparer(Of Integer)())

      Dim input As String = "Joe 164" + vbCrLf + _
                            "Sam 208" + vbCrLf + _
                            "Allison 211" + vbCrLf + _
                            "Gwen 171" + vbCrLf
      Dim pattern As String = "(?m)^(\w+)\s(\d+)\r*$"

      For Each match As Match In Regex.Matches(input, pattern, RegexOptions.Multiline)
         scores.Add(CInt(match.Groups(2).Value), match.Groups(1).Value)
      Next
      ' List scores in descending order. 
      For Each score As KeyValuePair(Of Integer, String) In scores
         Console.WriteLine("{0}: {1}", score.Value, score.Key)
      Next
   End Sub
End Module

Public Class DescendingComparer(Of T) : Implements IComparer(Of T)
   Public Function Compare(x As T, y As T) As Integer _
          Implements IComparer(Of T).Compare
      Return Comparer(Of T).Default.Compare(x, y) * -1       
   End Function
End Class
' The example displays the following output:
'    Allison: 211
'    Sam: 208
'    Gwen: 171
'    Joe: 164
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      SortedList<int, string> scores = new SortedList<int, string>(new DescendingComparer<int>());

      string input = "Joe 164\n" +  
                     "Sam 208\n" +  
                     "Allison 211\n" +  
                     "Gwen 171\n"; 
      string pattern = @"(?m)^(\w+)\s(\d+)\r*$";

      foreach (Match match in Regex.Matches(input, pattern, RegexOptions.Multiline))
         scores.Add(Convert.ToInt32(match.Groups[2].Value), match.Groups[1].Value);

      // List scores in descending order. 
      foreach (KeyValuePair<int, string> score in scores)
         Console.WriteLine("{0}: {1}", score.Value, score.Key);
   }
}

public class DescendingComparer<T> : IComparer<T>
{
   public int Compare(T x, T y) 
   {
      return Comparer<T>.Default.Compare(x, y) * -1;       
   }
}
// The example displays the following output:
//    Allison: 211
//    Sam: 208
//    Gwen: 171
//    Joe: 164

К началу

Однострочный режим

Параметр RegexOptions.Singleline или параметр встроенный s приводит к тому, что обработчик регулярных выражений обрабатывает входную строку как состоящую из одной строки. Это осуществляется путем изменения поведения элемента языка точки (.), таким образом, чтобы она соответствовала каждого символа, вместо соответствования каждого символа, за исключением знака новой строки \n или \u000A.

В следующем примере показано, как изменяется поведение элемента языка . при использовании параметра RegexOptions.Singleline. Регулярное выражение ^.+ начинается с начала строки и соответствует любому знаку. По умолчанию соответствие заканчивается в конце первой строки; шаблон регулярного выражения соответствует символу возврата каретки, \r или \u000D, но не соответствует \n. Поскольку параметр RegexOptions.Singleline интерпретирует всю строку ввода как единую строку, он сопоставляет каждый символ в строке ввода, включая \n.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "^.+"
      Dim input As String = "This is one line and" + vbCrLf + "this is the second."
      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine(Regex.Escape(match.Value))
      Next
      Console.WriteLine()
      For Each match As Match In Regex.Matches(input, pattern, RegexOptions.SingleLine)
         Console.WriteLine(Regex.Escape(match.Value))
      Next
   End Sub
End Module
' The example displays the following output:
'       This\ is\ one\ line\ and\r
'       
'       This\ is\ one\ line\ and\r\nthis\ is\ the\ second\.
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = "^.+";
      string input = "This is one line and" + Environment.NewLine + "this is the second.";
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine(Regex.Escape(match.Value));

      Console.WriteLine();
      foreach (Match match in Regex.Matches(input, pattern, RegexOptions.Singleline))
         Console.WriteLine(Regex.Escape(match.Value));
   }
}
// The example displays the following output:
//       This\ is\ one\ line\ and\r
//       
//       This\ is\ one\ line\ and\r\nthis\ is\ the\ second\.

Следующий пример эквивалентен предыдущему, за исключением того, что он использует параметр встроенный (?s) для включения однострочного параметра.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "(?s)^.+"
      Dim input As String = "This is one line and" + vbCrLf + "this is the second."

      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine(Regex.Escape(match.Value))
      Next
   End Sub
End Module
' The example displays the following output:
'       This\ is\ one\ line\ and\r\nthis\ is\ the\ second\.
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {      
      string pattern = "(?s)^.+";
      string input = "This is one line and" + Environment.NewLine + "this is the second.";

      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine(Regex.Escape(match.Value));
   }
}
// The example displays the following output:
//       This\ is\ one\ line\ and\r\nthis\ is\ the\ second\.

К началу

Только явные захваты

По умолчанию группы захвата определяются с помощью скобок в шаблон регулярного выражения. Именованные группы назначаются имя или номер параметром (?<имя> подвыражения) языка, тогда как неименованные группы доступны по индексу. В объекте GroupCollection неименованные группы идут перед именованными группами.

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

\b\(?((\w+),?\s?)+[\.!?]\)?

предназначен только для извлечения из документа предложений, которые заканчиваются точкой восклицательным знаком, или знаком вопроса. Только результирующие предложения (которые представлен объектом Match) представляют интерес. Отдельные слова в коллекции — нет.

Группы захвата, которые не используются впоследствии, могут быть дорогими, поскольку обработчик регулярных выражений доложен заполнить объекты как коллекции GroupCollection, так и коллекции CaptureCollection. В качестве альтернативы можно использовать параметр RegexOptions.ExplicitCapture или встроенный параметр n, чтобы указать, что единственно допустимые захваты являются явно именованными или нумерованными группами, обозначенными с помощью конструкции (?<имя> подвыражение).

В следующем примере отображаются сведения о совпадениях, возвращенных шаблоном регулярного выражения \b\(?((\w+),?\s?)+[\.!?]\)?, когда метод Match вызывается с и без параметра RegexOptions.ExplicitCapture. Как выходные данные первого вызова метода показывает, обработчик регулярных выражений полностью заполняет объекты коллекции GroupCollection и CaptureCollection сведениями о захваченных подстроках. Поскольку второй метод вызывается с options равным RegexOptions.ExplicitCapture, он не выполняет запись информацию о группах.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim input As String = "This is the first sentence. Is it the beginning " + _
                            "of a literary masterpiece? I think not. Instead, " + _
                            "it is a nonsensical paragraph."
      Dim pattern As String = "\b\(?((?>\w+),?\s?)+[\.!?]\)?"
      Console.WriteLine("With implicit captures:")
      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine("The match: {0}", match.Value)
         Dim groupCtr As Integer = 0
         For Each group As Group In match.Groups
            Console.WriteLine("   Group {0}: {1}", groupCtr, group.Value)
            groupCtr += 1
            Dim captureCtr As Integer = 0
            For Each capture As Capture In group.Captures
               Console.WriteLine("      Capture {0}: {1}", captureCtr, capture.Value)
               captureCtr += 1
            Next
         Next
      Next
      Console.WriteLine()
      Console.WriteLine("With explicit captures only:")
      For Each match As Match In Regex.Matches(input, pattern, RegexOptions.ExplicitCapture)
         Console.WriteLine("The match: {0}", match.Value)
         Dim groupCtr As Integer = 0
         For Each group As Group In match.Groups
            Console.WriteLine("   Group {0}: {1}", groupCtr, group.Value)
            groupCtr += 1
            Dim captureCtr As Integer = 0
            For Each capture As Capture In group.Captures
               Console.WriteLine("      Capture {0}: {1}", captureCtr, capture.Value)
               captureCtr += 1
            Next
         Next
      Next
   End Sub
End Module
' The example displays the following output:
'    With implicit captures:
'    The match: This is the first sentence.
'       Group 0: This is the first sentence.
'          Capture 0: This is the first sentence.
'       Group 1: sentence
'          Capture 0: This
'          Capture 1: is
'          Capture 2: the
'          Capture 3: first
'          Capture 4: sentence
'       Group 2: sentence
'          Capture 0: This
'          Capture 1: is
'          Capture 2: the
'          Capture 3: first
'          Capture 4: sentence
'    The match: Is it the beginning of a literary masterpiece?
'       Group 0: Is it the beginning of a literary masterpiece?
'          Capture 0: Is it the beginning of a literary masterpiece?
'       Group 1: masterpiece
'          Capture 0: Is
'          Capture 1: it
'          Capture 2: the
'          Capture 3: beginning
'          Capture 4: of
'          Capture 5: a
'          Capture 6: literary
'          Capture 7: masterpiece
'       Group 2: masterpiece
'          Capture 0: Is
'          Capture 1: it
'          Capture 2: the
'          Capture 3: beginning
'          Capture 4: of
'          Capture 5: a
'          Capture 6: literary
'          Capture 7: masterpiece
'    The match: I think not.
'       Group 0: I think not.
'          Capture 0: I think not.
'       Group 1: not
'          Capture 0: I
'          Capture 1: think
'          Capture 2: not
'       Group 2: not
'          Capture 0: I
'          Capture 1: think
'          Capture 2: not
'    The match: Instead, it is a nonsensical paragraph.
'       Group 0: Instead, it is a nonsensical paragraph.
'          Capture 0: Instead, it is a nonsensical paragraph.
'       Group 1: paragraph
'          Capture 0: Instead,
'          Capture 1: it
'          Capture 2: is
'          Capture 3: a
'          Capture 4: nonsensical
'          Capture 5: paragraph
'       Group 2: paragraph
'          Capture 0: Instead
'          Capture 1: it
'          Capture 2: is
'          Capture 3: a
'          Capture 4: nonsensical
'          Capture 5: paragraph
'    
'    With explicit captures only:
'    The match: This is the first sentence.
'       Group 0: This is the first sentence.
'          Capture 0: This is the first sentence.
'    The match: Is it the beginning of a literary masterpiece?
'       Group 0: Is it the beginning of a literary masterpiece?
'          Capture 0: Is it the beginning of a literary masterpiece?
'    The match: I think not.
'       Group 0: I think not.
'          Capture 0: I think not.
'    The match: Instead, it is a nonsensical paragraph.
'       Group 0: Instead, it is a nonsensical paragraph.
'          Capture 0: Instead, it is a nonsensical paragraph.
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "This is the first sentence. Is it the beginning " + 
                     "of a literary masterpiece? I think not. Instead, " + 
                     "it is a nonsensical paragraph.";
      string pattern = @"\b\(?((?>\w+),?\s?)+[\.!?]\)?";
      Console.WriteLine("With implicit captures:");
      foreach (Match match in Regex.Matches(input, pattern))
      {
         Console.WriteLine("The match: {0}", match.Value);
         int groupCtr = 0;
         foreach (Group group in match.Groups)
         {
            Console.WriteLine("   Group {0}: {1}", groupCtr, group.Value);
            groupCtr++;
            int captureCtr = 0;
            foreach (Capture capture in group.Captures)
            {
               Console.WriteLine("      Capture {0}: {1}", captureCtr, capture.Value);
               captureCtr++;
            }
         }
      }
      Console.WriteLine();
      Console.WriteLine("With explicit captures only:");
      foreach (Match match in Regex.Matches(input, pattern, RegexOptions.ExplicitCapture))
      {
         Console.WriteLine("The match: {0}", match.Value);
         int groupCtr = 0;
         foreach (Group group in match.Groups)
         {
            Console.WriteLine("   Group {0}: {1}", groupCtr, group.Value);
            groupCtr++;
            int captureCtr = 0;
            foreach (Capture capture in group.Captures)
            {
               Console.WriteLine("      Capture {0}: {1}", captureCtr, capture.Value);
               captureCtr++;
            }
         }
      }
   }
}
// The example displays the following output:
//    With implicit captures:
//    The match: This is the first sentence.
//       Group 0: This is the first sentence.
//          Capture 0: This is the first sentence.
//       Group 1: sentence
//          Capture 0: This
//          Capture 1: is
//          Capture 2: the
//          Capture 3: first
//          Capture 4: sentence
//       Group 2: sentence
//          Capture 0: This
//          Capture 1: is
//          Capture 2: the
//          Capture 3: first
//          Capture 4: sentence
//    The match: Is it the beginning of a literary masterpiece?
//       Group 0: Is it the beginning of a literary masterpiece?
//          Capture 0: Is it the beginning of a literary masterpiece?
//       Group 1: masterpiece
//          Capture 0: Is
//          Capture 1: it
//          Capture 2: the
//          Capture 3: beginning
//          Capture 4: of
//          Capture 5: a
//          Capture 6: literary
//          Capture 7: masterpiece
//       Group 2: masterpiece
//          Capture 0: Is
//          Capture 1: it
//          Capture 2: the
//          Capture 3: beginning
//          Capture 4: of
//          Capture 5: a
//          Capture 6: literary
//          Capture 7: masterpiece
//    The match: I think not.
//       Group 0: I think not.
//          Capture 0: I think not.
//       Group 1: not
//          Capture 0: I
//          Capture 1: think
//          Capture 2: not
//       Group 2: not
//          Capture 0: I
//          Capture 1: think
//          Capture 2: not
//    The match: Instead, it is a nonsensical paragraph.
//       Group 0: Instead, it is a nonsensical paragraph.
//          Capture 0: Instead, it is a nonsensical paragraph.
//       Group 1: paragraph
//          Capture 0: Instead,
//          Capture 1: it
//          Capture 2: is
//          Capture 3: a
//          Capture 4: nonsensical
//          Capture 5: paragraph
//       Group 2: paragraph
//          Capture 0: Instead
//          Capture 1: it
//          Capture 2: is
//          Capture 3: a
//          Capture 4: nonsensical
//          Capture 5: paragraph
//    
//    With explicit captures only:
//    The match: This is the first sentence.
//       Group 0: This is the first sentence.
//          Capture 0: This is the first sentence.
//    The match: Is it the beginning of a literary masterpiece?
//       Group 0: Is it the beginning of a literary masterpiece?
//          Capture 0: Is it the beginning of a literary masterpiece?
//    The match: I think not.
//       Group 0: I think not.
//          Capture 0: I think not.
//    The match: Instead, it is a nonsensical paragraph.
//       Group 0: Instead, it is a nonsensical paragraph.
//          Capture 0: Instead, it is a nonsensical paragraph.

Возможные интерпретации шаблона регулярного выражения \b\(?((?>\w+),?\s?)+[\.!?]\)? определены в следующей таблице.

Шаблон

Описание

\b

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

\(?

Выделить ноль или одно вхождение открывающей скобки ("(").

(?>\w+),?

Соответствует одному или нескольким буквенным символам, за которыми следует ноль или одна запятая. Не возвращаться назад при сопоставлении символов слова.

\s?

Выделить ноль или один символ пробела.

((\w+),? \s?)+

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

[\.!?]\)?

Соответствует любому из трех символов пунктуации, за которыми следует ноль или одна закрывающая скобка (")").

Можно также использовать встроенный элемент (?n) для подавления автоматических фиксаций. В следующем примере изменяется шаблон регулярного выражения из предыдущего примера для использования встроенного элемента (?n) вместо параметра RegexOptions.ExplicitCapture.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim input As String = "This is the first sentence. Is it the beginning " + _
                            "of a literary masterpiece? I think not. Instead, " + _
                            "it is a nonsensical paragraph."
      Dim pattern As String = "(?n)\b\(?((?>\w+),?\s?)+[\.!?]\)?"

      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine("The match: {0}", match.Value)
         Dim groupCtr As Integer = 0
         For Each group As Group In match.Groups
            Console.WriteLine("   Group {0}: {1}", groupCtr, group.Value)
            groupCtr += 1
            Dim captureCtr As Integer = 0
            For Each capture As Capture In group.Captures
               Console.WriteLine("      Capture {0}: {1}", captureCtr, capture.Value)
               captureCtr += 1
            Next
         Next
      Next
   End Sub
End Module
' The example displays the following output:
'       The match: This is the first sentence.
'          Group 0: This is the first sentence.
'             Capture 0: This is the first sentence.
'       The match: Is it the beginning of a literary masterpiece?
'          Group 0: Is it the beginning of a literary masterpiece?
'             Capture 0: Is it the beginning of a literary masterpiece?
'       The match: I think not.
'          Group 0: I think not.
'             Capture 0: I think not.
'       The match: Instead, it is a nonsensical paragraph.
'          Group 0: Instead, it is a nonsensical paragraph.
'             Capture 0: Instead, it is a nonsensical paragraph.
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "This is the first sentence. Is it the beginning " + 
                     "of a literary masterpiece? I think not. Instead, " + 
                     "it is a nonsensical paragraph.";
      string pattern = @"(?n)\b\(?((?>\w+),?\s?)+[\.!?]\)?";

      foreach (Match match in Regex.Matches(input, pattern))
      {
         Console.WriteLine("The match: {0}", match.Value);
         int groupCtr = 0;
         foreach (Group group in match.Groups)
         {
            Console.WriteLine("   Group {0}: {1}", groupCtr, group.Value);
            groupCtr++;
            int captureCtr = 0;
            foreach (Capture capture in group.Captures)
            {
               Console.WriteLine("      Capture {0}: {1}", captureCtr, capture.Value);
               captureCtr++;
            }
         }
      }
   }
}
// The example displays the following output:
//       The match: This is the first sentence.
//          Group 0: This is the first sentence.
//             Capture 0: This is the first sentence.
//       The match: Is it the beginning of a literary masterpiece?
//          Group 0: Is it the beginning of a literary masterpiece?
//             Capture 0: Is it the beginning of a literary masterpiece?
//       The match: I think not.
//          Group 0: I think not.
//             Capture 0: I think not.
//       The match: Instead, it is a nonsensical paragraph.
//          Group 0: Instead, it is a nonsensical paragraph.
//             Capture 0: Instead, it is a nonsensical paragraph.

Наконец, можно использовать встроенный элемент группы (?n:) для подавления автоматической записи по группам. В следующем примере изменяется предыдущий шаблон для подавления неименованных захватов внешней группы, ((?>\w+),?\s?). Обратите внимание, что это подавляет неименованные захваты также во внутренних группах.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim input As String = "This is the first sentence. Is it the beginning " + _
                            "of a literary masterpiece? I think not. Instead, " + _
                            "it is a nonsensical paragraph."
      Dim pattern As String = "\b\(?(?n:(?>\w+),?\s?)+[\.!?]\)?"

      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine("The match: {0}", match.Value)
         Dim groupCtr As Integer = 0
         For Each group As Group In match.Groups
            Console.WriteLine("   Group {0}: {1}", groupCtr, group.Value)
            groupCtr += 1
            Dim captureCtr As Integer = 0
            For Each capture As Capture In group.Captures
               Console.WriteLine("      Capture {0}: {1}", captureCtr, capture.Value)
               captureCtr += 1
            Next
         Next
      Next
   End Sub
End Module
' The example displays the following output:
'       The match: This is the first sentence.
'          Group 0: This is the first sentence.
'             Capture 0: This is the first sentence.
'       The match: Is it the beginning of a literary masterpiece?
'          Group 0: Is it the beginning of a literary masterpiece?
'             Capture 0: Is it the beginning of a literary masterpiece?
'       The match: I think not.
'          Group 0: I think not.
'             Capture 0: I think not.
'       The match: Instead, it is a nonsensical paragraph.
'          Group 0: Instead, it is a nonsensical paragraph.
'             Capture 0: Instead, it is a nonsensical paragraph.
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "This is the first sentence. Is it the beginning " + 
                     "of a literary masterpiece? I think not. Instead, " + 
                     "it is a nonsensical paragraph.";
      string pattern = @"\b\(?(?n:(?>\w+),?\s?)+[\.!?]\)?";

      foreach (Match match in Regex.Matches(input, pattern))
      {
         Console.WriteLine("The match: {0}", match.Value);
         int groupCtr = 0;
         foreach (Group group in match.Groups)
         {
            Console.WriteLine("   Group {0}: {1}", groupCtr, group.Value);
            groupCtr++;
            int captureCtr = 0;
            foreach (Capture capture in group.Captures)
            {
               Console.WriteLine("      Capture {0}: {1}", captureCtr, capture.Value);
               captureCtr++;
            }
         }
      }
   }
}
// The example displays the following output:
//       The match: This is the first sentence.
//          Group 0: This is the first sentence.
//             Capture 0: This is the first sentence.
//       The match: Is it the beginning of a literary masterpiece?
//          Group 0: Is it the beginning of a literary masterpiece?
//             Capture 0: Is it the beginning of a literary masterpiece?
//       The match: I think not.
//          Group 0: I think not.
//             Capture 0: I think not.
//       The match: Instead, it is a nonsensical paragraph.
//          Group 0: Instead, it is a nonsensical paragraph.
//             Capture 0: Instead, it is a nonsensical paragraph.

К началу

Скомпилированные регулярные выражения

По умолчанию интерпретируются регулярные выражения в .NET Framework. Когда создан экземпляр объекта Regex или вызван статический метод Regex, шаблон регулярного выражения анализируется в набор настраиваемых кодов операций и интерпретатор использует эти коды операций для выполнения регулярного выражения. Это включает в себя компромисс: стоимость инициализации обработчика регулярных выражений уменьшается за счет производительности среды выполнения.

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

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

Регулярное выражение может быть скомпилировано, только указав значение RegexOptions.Compiled параметру options конструктору класса Regex или статическому методу соответствия шаблону.Не доступно в качестве встроенного параметра.

Можно использовать скомпилированные регулярные выражения в вызовах как к статическим, так и экземплярным регулярным выражения. В статических регулярных выражениях параметр RegexOptions.Compiled передается параметру options метода сопоставления шаблонов регулярного выражения. В регулярных выражениях экземпляра он передается параметру options конструктора классов Regex. В обоих случаях это приводит к повышенной производительности.

Однако это улучшение производительности возникает только при следующих условиях:

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

  • Объект Regex не может выходить за пределы области действия, поэтому он может быть повторно использован.

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

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

Параметр RegexOptions.Compiled не связан с методом Regex.CompileToAssembly, создающим сборку специального назначения, которая содержит предопределенные скомпилированные регулярные выражения.

К началу

Игнорировать пробелы

По умолчанию пробел в шаблон регулярного выражения важен; он заставляет обработчик регулярных выражений сопоставлять знак пробела во входной строке. В результате регулярное выражение "\b\w+\s" и "\b\w+ " являются приблизительно равными регулярными выражениями. Кроме того при обнаружении знак номера (#) в шаблоне регулярного выражения, он интерпретируется как буквенный символ для сравнения.

Параметр RegexOptions.IgnorePatternWhitespace или параметр встроенный x изменяет поведение по умолчанию следующим образом:

  • Не преобразованные в escape-последовательность знаки пробела в шаблоне регулярного выражения игнорируется. Чтобы быть частью шаблона регулярного выражения, пробелы должны быть escape-преобразованы (например, \s или "\ ").

    Важное примечаниеВажно

    Пробел внутри класса знаков интерпретируется буквально независимо использования параметра RegexOptions.IgnorePatternWhitespace.Например шаблон регулярного выражения [ .,;:] соответствует любому одному знаку пробела, точке, запятой, точке с запятой или двоеточию.

  • Знак номера (#), интерпретируется как начало комментария, а не как буквенный символ. Весь текст в шаблоне регулярного выражения от символа # для конца строки интерпретируется как комментарий.

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

В следующем примере определяется следующий шаблон регулярного выражения:

\b \(? ( (?>\w+) ,? \s? )+ [\.!?] \)? # Matches an entire sentence.

Этот шаблон подобен шаблону, определенному в разделе Только явные захваты, за исключением того, что он использует параметр RegexOptions.IgnorePatternWhitespace, чтобы игнорировать пробелы шаблона.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim input As String = "This is the first sentence. Is it the beginning " + _
                            "of a literary masterpiece? I think not. Instead, " + _
                            "it is a nonsensical paragraph."
      Dim pattern As String = "\b \(? ( (?>\w+) ,?\s? )+  [\.!?] \)? # Matches an entire sentence."

      For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnorePatternWhitespace)
         Console.WriteLine(match.Value)
      Next
   End Sub
End Module
' The example displays the following output:
'       This is the first sentence.
'       Is it the beginning of a literary masterpiece?
'       I think not.
'       Instead, it is a nonsensical paragraph.
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "This is the first sentence. Is it the beginning " + 
                     "of a literary masterpiece? I think not. Instead, " + 
                     "it is a nonsensical paragraph.";
      string pattern = @"\b\(?((?>\w+),?\s?)+[\.!?]\)?";

      foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnorePatternWhitespace))
         Console.WriteLine(match.Value);
   }
}
// The example displays the following output:
//       This is the first sentence.
//       Is it the beginning of a literary masterpiece?
//       I think not.
//       Instead, it is a nonsensical paragraph.

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

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim input As String = "This is the first sentence. Is it the beginning " + _
                            "of a literary masterpiece? I think not. Instead, " + _
                            "it is a nonsensical paragraph."
      Dim pattern As String = "(?x)\b \(? ( (?>\w+) ,?\s? )+  [\.!?] \)? # Matches an entire sentence."

      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine(match.Value)
      Next
   End Sub
End Module
' The example displays the following output:
'       This is the first sentence.
'       Is it the beginning of a literary masterpiece?
'       I think not.
'       Instead, it is a nonsensical paragraph.
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "This is the first sentence. Is it the beginning " + 
                     "of a literary masterpiece? I think not. Instead, " + 
                     "it is a nonsensical paragraph.";
      string pattern = @"(?x)\b \(? ( (?>\w+) ,?\s? )+  [\.!?] \)? # Matches an entire sentence.";

      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine(match.Value);
   }
}
// The example displays the following output:
//       This is the first sentence.
//       Is it the beginning of a literary masterpiece?
//       I think not.
//       Instead, it is a nonsensical paragraph.

К началу

Режим справа налево

По умолчанию обработчик регулярных выражений ищет слева направо. Можно обратить направление поиска с помощью параметра RegexOptions.RightToLeft. Поиск автоматически начинается с позиции последнего знака строки. Для методов соответствия шаблону, которые включают параметр начальной позиции, например Regex.Match(String, Int32) начальная позиция является индексом положения самого правого знака, с которой начать поиск.

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

Режим шаблон с направлением письма справа налево доступен только, указав значение RegexOptions.RightToLeft параметру options конструктора классов Regex или статическому методу соответствия шаблону.Не доступно в качестве встроенного параметра.

Параметр RegexOptions.RightToLeft изменяет только направление поиска; он не интерпретирует шаблон регулярного выражения справа налево. Например регулярное выражение \bb\w+\s соответствует словам, начинающимся с буквы "b" и за которыми следуют символ пробела. В следующем примере строка ввода состоит из трех слов, включающие один или несколько символов "b". Первое слово начинается с "b", второе заканчивается "b" и третье включает два символа "b" в середине слова. Как выходные данные в примере показывают, только первое слово соответствует шаблону регулярного выражения.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "\bb\w+\s"
      Dim input As String = "builder rob rabble"
      For Each match As Match In Regex.Matches(input, pattern, RegexOptions.RightToLeft)
         Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)     
      Next
   End Sub
End Module
' The example displays the following output:
'       'builder ' found at position 0.
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\bb\w+\s";
      string input = "builder rob rabble";
      foreach (Match match in Regex.Matches(input, pattern, RegexOptions.RightToLeft))
         Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);     
   }
}
// The example displays the following output:
//       'builder ' found at position 0.

Также обратите внимание, что утверждение просмотра вперед (элемент языка (?=часть выражения)) и утверждение просмотра назад (элемент языка (?<=часть выражения)) не изменяют направление. Утверждения просмотра вперед смотрят направо; утверждения просмотра назад — налево. Например регулярное выражение (?<=\d{1,2}\s)\w+,*\s\d{4} использует для проверки даты, которая предшествуют имени месяца, утверждение просмотра назад. Регулярное выражение соответствует месяцу и году. Сведения об утверждениях просмотра вперед назад см. в разделе Конструкции группирования.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim inputs() As String = { "1 May 1917", "June 16, 2003" }
      Dim pattern As String = "(?<=\d{1,2}\s)\w+,?\s\d{4}"

      For Each input As String In inputs
         Dim match As Match = Regex.Match(input, pattern, RegexOptions.RightToLeft)
         If match.Success Then
            Console.WriteLine("The date occurs in {0}.", match.Value)
         Else
            Console.WriteLine("{0} does not match.", input)
         End If
      Next
   End Sub
End Module
' The example displays the following output:
'       The date occurs in May 1917.
'       June 16, 2003 does not match.
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string[] inputs = { "1 May 1917", "June 16, 2003" };
      string pattern = @"(?<=\d{1,2}\s)\w+,?\s\d{4}";

      foreach (string input in inputs)
      {
         Match match = Regex.Match(input, pattern, RegexOptions.RightToLeft);
         if (match.Success)
            Console.WriteLine("The date occurs in {0}.", match.Value);
         else
            Console.WriteLine("{0} does not match.", input);
      }
   }
}
// The example displays the following output:
//       The date occurs in May 1917.
//       June 16, 2003 does not match.

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

Шаблон

Описание

(?<=\d{1,2}\s)

Начало соответствия должно предшествоваться одним или двумя десятичными цифрами, за которым следует пробел.

\w+

Совпадение с одним или несколькими символами слова.

,*

Выделить ноль или один символ запятой.

\s

Соответствует пробелу.

\d{4}

Совпадение с четырьмя десятичными цифрами.

К началу

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

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

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

ECMAScript-совместимое поведение доступно только, указав значение RegexOptions.ECMAScript параметру options конструктора классов Regex или статического метода соответствия шаблону.Не доступно в качестве встроенного параметра.

Параметр RegexOptions.ECMAScript можно объединять только с параметрами RegexOptions.IgnoreCase и RegexOptions.Multiline. Использование любого другого параметра в регулярном выражении приводит к ArgumentOutOfRangeException.

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

  • Синтаксис класса символов. Поскольку канонические регулярные выражения поддерживают Юникод, тогда как ECMAScript нет, классы знаков в ECMAScript имеют более ограниченный синтаксис и некоторые элементы языка класса знаков имеют разные значения. Например, ECMAScript не поддерживает элементы языка, такие как категории Юникода или блочные элементы \p и \P. Подобным образом элемент \w, который соответствует символу слова, эквивалентен классу знаков [a-zA-Z_0-9] при использовании ECMAScript и [\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}\p{Lm}] при использовании канонического поведения. Дополнительные сведения см. в разделе Классы знаков.

    В следующем примере показано различие между каноническим и ECMAScript соответствием шаблону. Он определяет регулярное выражение \b(\w+\s*)+, которое совпадает со словами, за которыми следуют пробельные символы. Входные данные состоит из двух строк, одна, которая использует набор латинского алфавита и другая, использующий набор символов кириллицы. Как выходные данные показывают, вызов метода Regex.IsMatch(String, String, RegexOptions), который использует сопоставление ECMAScript не может сопоставить слова в кириллице, а вызов метода, который использует каноническое сопоставление, может это сделать.

    Imports System.Text.RegularExpressions
    
    Module Example
       Public Sub Main()
          Dim values() As String = { "целый мир", "the whole world" }
          Dim pattern As String = "\b(\w+\s*)+"
          For Each value In values
             Console.Write("Canonical matching: ")
             If Regex.IsMatch(value, pattern)
                Console.WriteLine("'{0}' matches the pattern.", value)
             Else
                Console.WriteLine("{0} does not match the pattern.", value)
             End If
    
             Console.Write("ECMAScript matching: ")
             If Regex.IsMatch(value, pattern, RegexOptions.ECMAScript)
                Console.WriteLine("'{0}' matches the pattern.", value)
             Else
                Console.WriteLine("{0} does not match the pattern.", value)
             End If
             Console.WriteLine()
          Next
       End Sub
    End Module
    ' The example displays the following output:
    '       Canonical matching: 'целый мир' matches the pattern.
    '       ECMAScript matching: целый мир does not match the pattern.
    '       
    '       Canonical matching: 'the whole world' matches the pattern.
    '       ECMAScript matching: 'the whole world' matches the pattern.
    
    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          string[] values = { "целый мир", "the whole world" };
          string pattern = @"\b(\w+\s*)+";
          foreach (var value in values)
          {
             Console.Write("Canonical matching: ");
             if (Regex.IsMatch(value, pattern))
                Console.WriteLine("'{0}' matches the pattern.", value);
             else
                Console.WriteLine("{0} does not match the pattern.", value);
    
             Console.Write("ECMAScript matching: ");
             if (Regex.IsMatch(value, pattern, RegexOptions.ECMAScript))
                Console.WriteLine("'{0}' matches the pattern.", value);
             else
                Console.WriteLine("{0} does not match the pattern.", value);
             Console.WriteLine();
          }
       }
    }
    // The example displays the following output:
    //       Canonical matching: 'целый мир' matches the pattern.
    //       ECMAScript matching: целый мир does not match the pattern.
    //       
    //       Canonical matching: 'the whole world' matches the pattern.
    //       ECMAScript matching: 'the whole world' matches the pattern.
    
  • Ссылающиеся сами на себя группы захвата. Класс сбора регулярного выражения с обратной ссылкой на самого себя должен обновляться на каждом шаге сбора. Как показано в следующем примере, эта возможность позволяет регулярному выражению ((a+)(\1) ?)+ соответствовать входной строке " aa aaaa aaaaaa " при использовании ECMAScript, но не при использовании канонического сопоставлении.

    Возможные интерпретации регулярного выражения определены в следующей таблице.

    Шаблон

    Описание

    (a+)

    Соответствует букве "a" один или несколько раз. Это вторая группа записи.

    (\1)

    Соответствует подстроке, захваченной первой группой захвата. Это третья группа записи.

    ?

    Выделить ноль или один символ пробела.

    ((a+)(\1) ?)+

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

  • Разрешение неоднозначностей между восьмеричными escape-символами и обратными ссылками. В следующей таблице приведены различия в интерпретации восьмеричных чисел и обратных ссылок регулярными выражениями ECMAScript и каноническими регулярными выражениями.

    Регулярное выражение

    Каноническое поведение

    Поведение в ECMAScript

    \0, затем следуют восьмеричные цифры 0-2

    Интерпретируется как восьмеричное. Например \044 всегда интерпретируется как восьмеричное значение и означает "$".

    Аналогичное поведение.

    \, затем следует цифра от 1 до 9 без последующих нескольких десятичных цифр,

    Интерпретируется как обратная ссылка. Например \9 всегда означает обратную ссылку 9, даже если девятая группа захвата не существует. Если группы захвата не существует, парсер регулярных выражений создает ArgumentException.

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

    \, затем следует цифра от 1 до 9 с последующими несколькими десятичными цифрами

    Цифры интерпретируется как десятичное значение. Если существует такая группа захвата, то это интерпретируется как обратная ссылка.

    В противном случае интерпретировать начальные восьмеричные цифры до восьмеричного 377;то есть рассматривать только младшие 8 бит значения. Остальные цифры интерпретируется как литералы. Например, в выражении \3000, если существует группа захвата 300, интерпретируется как обратная ссылка 300; если группы захвата 300 не существует, оно интерпретируется как восьмеричное число 300, за которым следует 0.

    Интерпретируется как обратная ссылка, преобразуя столько цифр, сколько возможно в десятичное значение, которое может обращаться к записи. Если ни одна цифра не может быть преобразована, то первые восьмеричные цифры интерпретируются как восьмеричное число до восьмеричного значения 377; остальные цифры интерпретируются как литералы.

К началу

Сравнение с использованием инвариантного языка и региональных параметров

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

Однако данное поведение является нежелательным для некоторых типов сравнений, особенно при сравнении пользовательского ввода с названиями системных ресурсов, таких как пароли, файлы или URL-адреса. Этот сценарий показан в приведенном ниже примере. Код предназначен для того, чтобы заблокировать доступ к любому ресурсу, чей URL имеет префикс FILE://. Регулярное выражение пытается выполнить сопоставление без учета регистра со строкой, используя регулярное выражение $FILE://. Однако, если текущий языка и региональных параметров системы является tr-TR (турецкий — Турция) "I"не является заглавным эквивалентом "i". В результате вызов метода Regex.IsMatch возвращает false и разрешается доступ к файлу.

Dim defaultCulture As CultureInfo = Thread.CurrentThread.CurrentCulture
Thread.CurrentThread.CurrentCulture = New CultureInfo("tr-TR")

Dim input As String = "file://c:/Documents.MyReport.doc"
Dim pattern As String = "$FILE://"

Console.WriteLine("Culture-sensitive matching ({0} culture)...", _
                  Thread.CurrentThread.CurrentCulture.Name)
If Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase) Then
   Console.WriteLine("URLs that access files are not allowed.")      
Else
   Console.WriteLine("Access to {0} is allowed.", input)
End If

Thread.CurrentThread.CurrentCulture = defaultCulture
' The example displays the following output:
'       Culture-sensitive matching (tr-TR culture)...
'       Access to file://c:/Documents.MyReport.doc is allowed.
CultureInfo defaultCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR");

string input = "file://c:/Documents.MyReport.doc";
string pattern = "FILE://";

Console.WriteLine("Culture-sensitive matching ({0} culture)...", 
                  Thread.CurrentThread.CurrentCulture.Name);
if (Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase))
   Console.WriteLine("URLs that access files are not allowed.");      
else
   Console.WriteLine("Access to {0} is allowed.", input);

Thread.CurrentThread.CurrentCulture = defaultCulture;
// The example displays the following output:
//       Culture-sensitive matching (tr-TR culture)...
//       Access to file://c:/Documents.MyReport.doc is allowed.
ПримечаниеПримечание

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

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

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

Сравнение с использованием инвариантного языка и региональных параметров доступно только, указав значение RegexOptions.CultureInvariant параметру options конструктору классов Regex или статическому методу соответствия шаблону.Не доступно в качестве встроенного параметра.

Следующий пример идентичен предыдущему примеру, за исключением того, что статический метод Regex.IsMatch(String, String, RegexOptions) вызывается с параметрами, которые включают RegexOptions.CultureInvariant. Даже если в качестве текущего языка и региональных параметров задано значение "Турецкий (Турция)", обработчик регулярных выражений может успешно сопоставить "FILE"и "file" и блокировать доступ к файловому ресурсу.

Dim defaultCulture As CultureInfo = Thread.CurrentThread.CurrentCulture
Thread.CurrentThread.CurrentCulture = New CultureInfo("tr-TR")

Dim input As String = "file://c:/Documents.MyReport.doc"
Dim pattern As String = "$FILE://"

Console.WriteLine("Culture-insensitive matching...")
If Regex.IsMatch(input, pattern, _
               RegexOptions.IgnoreCase Or RegexOptions.CultureInvariant) Then
   Console.WriteLine("URLs that access files are not allowed.")      
Else
   Console.WriteLine("Access to {0} is allowed.", input)
End If
Thread.CurrentThread.CurrentCulture = defaultCulture
' The example displays the following output:
'        Culture-insensitive matching...
'        URLs that access files are not allowed.
CultureInfo defaultCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR");

string input = "file://c:/Documents.MyReport.doc";
string pattern = "FILE://";

Console.WriteLine("Culture-insensitive matching...");
if (Regex.IsMatch(input, pattern, 
                  RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)) 
   Console.WriteLine("URLs that access files are not allowed.");
else
   Console.WriteLine("Access to {0} is allowed.", input);

Thread.CurrentThread.CurrentCulture = defaultCulture;
// The example displays the following output:
//       Culture-insensitive matching...
//       URLs that access files are not allowed.

К началу

См. также

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

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