Share via


정규식 옵션

기본적으로 정규식 패턴에서 리터럴 문자와 입력 문자열을 비교하는 것은 대/소문자를 구분하며 정규식 패턴의 공백은 리터럴 공백 문자로 해석되며 정규식의 캡처링 그룹은 암시적/명시적으로 명명됩니다. 정규식 옵션을 지정하여 기본 정규식 동작의 여러 가지 측면을 수정할 수 있습니다. 다음 표에 나열된 이러한 옵션은 인라인을 정규식 패턴의 일부로 포함하거나 System.Text.RegularExpressions.Regex 클래스 생성자 또는 정적 패턴 일치 메서드를 System.Text.RegularExpressions.RegexOptions 열거 값으로 제공할 수 있습니다.

RegexOptions 멤버

인라인 문자

결과

None

사용할 수 없음

기본 동작 사용. 자세한 정보는 기본 옵션을 참조하십시오.

IgnoreCase

i

대/소문자를 구분하지 않는 일치 사용. 자세한 내용은 대/소문자를 구분하지 않는 일치를 참조하십시오.

Multiline

m

^ 및 $가 각 줄의 시작과 끝 부분(입력 문자열의 시작과 끝 부분 대신)에 일치하는 여러 줄 모드를 사용합니다. 자세한 내용은 여러 줄 모드를 참조하십시오.

Singleline

s

마침표(.)가 모든 문자(\n을 제외하고 모든 문자 대신)와 일치하는 한 줄 모드를 사용합니다. 자세한 내용은 한 줄 모드를 참조하십시오.

ExplicitCapture

n

명명되지 않는 그룹을 캡처링하지 않습니다. (?<name> subexpression) 형식의 명시적으로 명명되거나 번호가 매겨진 그룹만 유효한 캡처가 되도록 지정합니다. 자세한 내용은 명시적 캡처 전용을 참조하십시오.

Compiled

사용할 수 없음

정규식을 어셈블리에 컴파일합니다. 자세한 내용은 컴파일된 정규식을 참조하십시오.

IgnorePatternWhitespace

x

패턴에서 이스케이프되지 않은 공백을 제외하고 숫자 기호(#) 다음에 주석을 사용하도록 설정합니다. 자세한 내용은 공백 무시를 참조하십시오.

RightToLeft

사용할 수 없음

검색 방향을 변경합니다. 왼쪽에서 오른쪽이 아니라 오른쪽에서 왼쪽으로 검색합니다. 자세한 내용은 오른쪽에서 왼쪽으로 작업 모드를 참조하십시오.

ECMAScript

사용할 수 없음

해당 식에 ECMAScript 규격 동작을 사용 가능하게 합니다. 자세한 내용은 ECMAScript 일치 동작을 참조하십시오.

CultureInvariant

사용할 수 없음

언어의 문화적 차이를 무시합니다. 자세한 내용은 고정 문화권을 사용하여 비교를 참조하십시오.

옵션 지정

세 가지 방법 중 하나로 정규식 옵션을 지정할 수 있습니다.

  • Regex.Regex(String, RegexOptions) 또는 Regex.Match(String, String, RegexOptions) 같은 System.Text.RegularExpressions.Regex 클래스 생성자 또는 정적(Visual Basic에서는 Shared) 패턴 일치 메서드의 options 매개 변수에서 options 매개 변수는 비트 수 또는 System.Text.RegularExpressions.RegexOptions 열거 값의 조합입니다.

    다음 예제에서 이에 대해 설명합니다. 문자 "d"로 시작하는 단어를 식별할 때 대/소문자를 구분하지 않는 일치를 사용하고 패턴 공백을 무시하도록 Regex.Match(String, String, RegexOptions) 메서드의 options 매개 변수를 사용합니다.

    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.IgnoreCaseRegexOptions.IgnorePatternWhitespace 옵션을 사용하도록 설정하고 RegexOptions.MultilineRegexOptions.Singleline 옵션을 해제합니다. 모든 정규식 옵션은 기본적으로 사용 설정이 해제되어 있습니다.

참고참고

생성자 또는 메서드 호출의 options 매개 변수에 지정된 정규식 옵션이 정규식 패턴에 지정된 인라인 옵션과 충돌하는 경우 인라인 옵션이 사용됩니다.

다음 다섯 가지 정규식 옵션은 옵션 매개 변수 및 인라인을 모두 설정할 수 있습니다.

다음 다섯 가지 정규식 옵션은 options 매개 변수를 사용하여 설정할 수 있지만 인라인으로는 설정할 수 없습니다.

옵션 결정

읽기 전용 Regex.Options 속성의 값을 검색하여 인스턴스화했을 때 Regex 개체에 어떤 옵션이 제공되었는지 확인할 수 있습니다. 이 속성은 Regex.CompileToAssembly 메서드에서 만든 컴파일된 정규식에 정의된 옵션을 확인하는 데 특히 유용합니다.

RegexOptions.None을 제외한 옵션이 있는지 테스트하려면 Regex.Options 속성의 값과 관심이 있는 RegexOptions 값으로 AND 연산을 수행합니다. 그런 다음 결과는 해당 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 인라인 옵션은 대/소문자를 구분하지 않는 일치를 제공합니다. 기본적으로 현재 문화권의 대/소문자 규칙이 사용됩니다.

다음 예제에서는 "the"로 시작하는 모든 단어를 찾는 정규식 패턴 \bthe\w*\b를 정의합니다. Match 메서드에 대한 첫 번째 호출은 기본적인 대/소문자 구분 비교를 사용하기 때문에 출력은 문장을 시작하는 문자열 "The"가 일치하지 않음을 보여줍니다. 옵션이 IgnoreCase로 설정되어 있을 경우 Match 메서드가 호출되면 일치됩니다.

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 매개 변수 대신 인라인 옵션을 사용하도록 이전 예제의 정규식 패턴을 수정합니다. 첫 번째 패턴은 문자열 "the"에서 문자 "t"에만 적용되는 그룹화 구문의 대/소문자를 구분하지 않는 옵션을 정의합니다. 옵션 구문은 패턴의 시작 부분에서 발생하기 때문에 두 번째 패턴은 전체 정규식에 대/소문자를 구분하지 않는 옵션을 적용합니다.

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

하나 이상의 10진수를 찾습니다. 이 그룹은 두 번째 캡처링 그룹입니다.

\r?

0개 또는 한 개의 캐리지 리턴 문자를 찾습니다.

$

선의 끝에서 끝납니다.

다음 예제는 인라인 옵션 (?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\.

맨 위로 이동

명시적 캡처의 경우에만.

기본적으로 캡처링 그룹은 정규식 패턴에서 괄호를 사용하여 정의됩니다. 명명된 그룹은 (?<name> subexpression) language 옵션으로 이름 또는 숫자를 할당하지만 명명되지 않은 그룹은 인덱스로 액세스할 수 있습니다. GroupCollection 개체에서 명명된 그룹은 명명되지 않은 그룹 앞에 나옵니다.

그룹화 구문은 종종 여러 언어 요소에 수량자를 적용하는 데만 사용되며 캡처된 부분 문자열은 관계가 없습니다. 예를 들어, 다음 정규식의 경우:

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

문서에서 마침표, 느낌표 또는 물음표로 끝나는 정확한 문장에만, 결과 문장에만 사용됩니다(Match 개체로 표현됨). 컬렉션의 개별 단어가 아닙니다.

이후에 사용되지 않는 캡처링 그룹은 정규식 엔진이 GroupCollectionCaptureCollection 컬렉션 개체를 모두 채워야 하기 때문에 비용이 많이 들 수 있습니다. 대신, RegexOptions.ExplicitCapture 옵션 또는 n 인라인 옵션을 사용하여 유일하게 유효한 캡처가 (?<이름> 부분식) 구조로 지정된 명시적으로 명명되거나 번호가 지정된 그룹임을 지정할 수 있습니다.

다음 예제에서는 Match 메서드가 RegexOptions.ExplicitCapture 옵션을 사용하거나 사용하지 않고 호출되는 경우 \b\(?((\w+),?\s?)+[\.!?]\)? 정규식 패턴에서 반환되는 일치 정보를 표시합니다. 첫 번째 메서드 호출의 출력이 표시되기 때문에 정규식 엔진은 GroupCollectionCaptureCollection 컬렉션 개체를 캡처된 부분 문자열에 대한 정보로 완전히 채웁니다. 두 번째 메서드는 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

단어 경계에서 시작하십시오.

\(?

여는 괄호("(") 0개 또는 한 개를 찾습니다.

(?>\w+),?

0개 또는 하나의 쉼표 뒤에 하나 이상의 단어 문자를 일치시킵니다. 문자와 일치하는 경우 역추적하지 마십시오.

\s?

0개 또는 한 개의 공백 문자를 일치시킵니다.

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

하나 이상의 단어 문자, 0개 또는 1개의 쉼표, 공백 문자가 한 번 이상 나타나는 조합을 일치하십시오.

[\.!?]\)?

세 가지 문장 부호, 그 뒤에 0개 이상의 닫는 괄호 (")")를 찾습니다.

자동 캡처를 표시하지 않는 (?n) 인라인 요소를 사용할 수도 있습니다. 다음 예제에서는 RegexOptions.ExplicitCapture 옵션 대신 (?n) 인라인 요소를 사용하도록 이전 정규식 패턴을 수정합니다.

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 메서드가 호출될 때 정규식 패턴은 사용자 지정 opcode의 집합으로 구문 분석되고 인터프리터는 이러한 opcode를 사용하여 정규식을 실행합니다. 여기에는 균형 조절이 필요합니다. 정규식 엔진을 초기화하는 비용을 최소화하면 런타임 성능이 떨어집니다.

RegexOptions.Compiled 옵션을 사용하여 해석된 정규식 대신 컴파일할 수 있습니다. 이 경우 패턴이 정규식 엔진으로 전달되면 opcode로 전달된 다음 공통 언어 런타임으로 직접 전달될 수 있는 MSIL(Microsoft intermediate language)로 변환됩니다. 컴파일된 정규식은 초기화 시간이 느려지는 대신 런타임 성능을 최대화합니다.

참고참고

정규식은 RegexOptions.Compiled 값을 Regex 클래스 생성기 또는 정적 패턴 일치 메서드의 options 매개 변수에 전달해야만 컴파일할 수 있습니다.인라인 옵션으로 사용할 수 없습니다.

정적 및 인스턴스 정규식에 대한 호출에서 컴파일된 정규식을 사용할 수 있습니다. 정적 정규식에서 RegexOptions.Compiled 옵션은 정규식 패턴 일치 메서드의 options 매개 변수로 전달됩니다. 인스턴스 정규식에서는 Regex 클래스 생성자의 options 매개 변수에 전달됩니다. 두 경우 모두 향상된 성능 결과를 갖습니다.

그러나 이 성능 개선은 다음과 같은 조건에서 발생합니다.

  • 특정 정규식을 나타내는 Regex 개체는 정규식 패턴 일치 메서드를 여러 번 호출하는 데 사용됩니다.

  • Regex 개체는 다시 사용할 수 있도록 범위를 벗어나는 것이 허용되지 않습니다.

  • 정적 정규식은 정규식 패턴 일치 메서드에 대한 여러 번 호출에 사용됩니다. (정적 메서드 호출에 사용되는 정규식은 정규식 엔진에서 캐시되므로 성능을 향상시킬 수 있습니다.)

참고참고

RegexOptions.Compiled 옵션은 Regex.CompileToAssembly 메서드와 관련이 없으며 미리 정의된 컴파일된 정규식을 포함하는 특수 목적 어셈블리를 만듭니다.

맨 위로 이동

공백 무시

기본적으로 정규식 패턴의 공백은 중요하며 정규식 엔진이 입력 문자열에서 공백 문자를 찾도록 합니다. 이 때문에 정규식 "\b\w+\s"와 "\b\w+ "는 거의 동일한 정규식이 됩니다. 뿐만 아니라, 숫자 기호(#)가 정규식 패턴에서 발생하면 일치할 리터럴 문자로 해석됩니다.

RegexOptions.IgnorePatternWhitespace 옵션 또는 x 인라인 옵션은 이 기본 동작을 다음과 같이 변경합니다.

  • 정규식 패턴에서 이스케이프되지 않은 공백은 무시됩니다. 정규식 패턴의 일부로 공백 문자는 이스케이프되어야 합니다(예: \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) 같은 시작 위치 매개 변수를 포함하는 패턴 일치 메서드의 경우 시작 위치는 검색이 시작되는 가장 오른쪽 문자 위치의 인덱스입니다.

참고참고

오른쪽에서 왼쪽 패턴 모드는 Regex 클래스 생성자 또는 정적 패턴 일치 메서드의 options 매개 변수에 대해 RegexOptions.RightToLeft 값을 제공해야만 사용할 수 있습니다.인라인 옵션으로 사용할 수 없습니다.

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+

둘 이상의 단어 문자를 찾습니다.

,*

0개 또는 한 개의 쉼표 문자를 찾습니다.

\s

공백 문자를 찾습니다.

\d{4}

네 개의 10진수를 찾습니다.

맨 위로 이동

ECMAScript 일치 동작

기본적으로 정규식 엔진은 정규식 패턴을 입력 텍스트에 일치시킬 때 정식 동작을 사용합니다. 그러나 정규식 엔진이 RegexOptions.ECMAScript 옵션을 지정하여 ECMAScript 일치 동작을 사용하도록 지시합니다.

참고참고

ECMAScript 호환 동작은 RegexOptions.ECMAScript 값을 Regex 클래스 생성기 또는 정적 패턴 일치 메서드의 options 매개 변수에 전달해야만 사용할 수 있습니다.인라인 옵션으로 사용할 수 없습니다.

RegexOptions.ECMAScript 옵션은 RegexOptions.IgnoreCaseRegexOptions.Multiline 옵션과 함께만 사용할 수 있습니다. 정규식의 다른 옵션을 사용하면 ArgumentOutOfRangeException이 발생합니다.

ECMAScript 및 정식 정규식의 동작은 문자 클래스 구문, 자체 참조 캡처링 그룹 및 8진수 역참조 해석 등 세 가지 영역에서 다릅니다.

  • 문자 클래스 구문. ECMAScript 정식 정규식은 유니코드를 지원하는 반면 ECMAScript는 지원하지 않기 때문에 ECMAScript의 문자 클래스는 더 제한된 구문을 가지며 일부 문자 클래스 언어 요소는 다른 의미를 갖습니다. 예를 들어, ECMAScript는 유니코드 범주 또는 블록 요소 \p 및 \P 같은 언어 요소는 지원하지 않습니다. 마찬가지로 단어 문자를 일치시키는 \w 요소는 ECMAScript를 사용할 때 [a-zA-Z_0-9] 문자 클래스 및 정식 동작을 사용할 때 [\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}\p{Lm}]와 동일합니다. 자세한 내용은 문자 클래스을 참조하십시오.

    다음 예제는 정식 및 ECMAScript 패턴 일치 사이의 차이를 보여줍니다. 단어 다음에 공백 문자를 찾는 정규식 \b(\w+\s*)+를 정의합니다. 입력은 두 문자로 구성되는데, 하나는 라틴 문자이고 다른 하나는 키릴 문자 집합입니다. 출력에 표시된 것처럼 ECMAScript 일치를 사용하는 Regex.IsMatch(String, String, RegexOptions) 메서드에 대한 호출은 키릴 단어를 일치시키는 반면, 정식 일치를 사용하는 메서드 호출은 이러한 단어를 일치시킵니다.

    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.
    
  • 자체 참조 캡처링 그룹. 자체 역참조가 있는 정규식 캡처 클래스는 각 캡처를 반복할 때마다 업데이트해야 합니다. 다음 예에서 볼 수 있듯이 이 기능을 사용하면 ECMAScript를 사용할 때 정규식 ((a+)(\1) ?)+이 입력 문자열 " aa aaaa aaaaaa "를 일치시킬 수 있지만 정식 일치를 사용할 때는 일치시킬 수 없습니다.

    정규식은 다음 표에서와 같이 정의됩니다.

    패턴

    설명

    (a+)

    문자 "a"를 한 번 이상 찾습니다. 이 그룹은 두 번째 캡처링 그룹입니다.

    (\1)

    첫 번째 캡처링 그룹에 의해 캡처된 부분 문자열을 일치시킵니다. 이 그룹은 세 번째 캡처링 그룹입니다.

    ?

    0개 또는 한 개의 공백 문자를 일치시킵니다.

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

    하나 이상의 "a" 문자 다음에 첫 번째 캡처링 그룹과 일치하는 문자열 다음에 0개 또는 하나의 공백 문자가 한 번 이상 나타나는 패턴을 찾습니다. 이 그룹은 첫 번째 캡처링 그룹입니다.

  • 8 진수 이스케이프와 역참조 간의 모호성을 해결합니다. 다음 표에는 정식 정규식과 ECMAScript 정규식에서 8진수 및 역참조를 어떻게 해석하는지 그 차이점을 보여 줍니다.

    정규식

    정식 동작

    ECMAScript 동작

    \0 다음에 0 ~ 2개의 8진수

    8진수로 해석합니다. 예를 들어, \044는 항상 8진수 값으로 해석되고 "$"를 의미합니다.

    동작이 동일합니다.

    \ 다음에 1에서 9 사이의 숫자가 있고 그 다음에 또 다른 10진수가 없습니다.

    역참조로 해석합니다. 예를 들어, \9는 9번째 캡처링 그룹이 없더라도 항상 역참조 9로 해석됩니다. 캡처링 그룹이 없는 경우에는 정규식 파서에서 ArgumentException이 throw됩니다.

    단일 10진수 캡처링 그룹이 있으면 그 숫자에 대한 역참조로 해석하고, 그렇지 않으면 값을 리터럴로 해석합니다.

    \ 다음에 1에서 9 사이의 숫자가 있고 그 다음에 또 다른 10진수가 있습니다.

    숫자를 10 진수 값으로 해석합니다. 해당 캡처링 그룹이 있을 경우에는 해당 식을 역참조로 해석합니다.

    그렇지 않으면 선행 8진수를 8진수 377까지 해석합니다. 즉, 값의 하위 8비트만 고려합니다. 나머지 숫자는 리터럴로 해석합니다. 예를 들어, 식 \3000의 경우 캡처링 그룹 300이 있으면 역참조 300으로 해석합니다. 캡처링 그룹 300이 없으면 8진수 300 다음에 0이 있는 것으로 해석합니다.

    캡처에 참조할 수 있는 10진수에 가능한 많은 자릿수로 변환하여 역참조로 해석합니다. 변환할 수 있는 숫자가 없는 경우에는 선행 8진수를 사용하여 8진수 377까지를 8진수로 해석하고 나머지 숫자는 리터럴로 해석합니다.

맨 위로 이동

고정 문화권을 사용하여 비교

기본적으로 정규식 엔진이 대/소문자를 구분하지 않는 비교를 수행할 때 현재 문화권의 대/소문자 규칙을 사용하여 동일한 대문자와 소문자를 확인합니다.

그러나 이 동작은 일부 형식의 비교, 특히 사용자 입력을 암호, 파일 또는 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 값을 Regex 클래스 생성기 또는 정적 패턴 일치 메서드의 options 매개 변수에 전달해야만 사용할 수 있습니다.인라인 옵션으로 사용할 수 없습니다.

다음 예제는 정적 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.

맨 위로 이동

참고 항목

개념

정규식 언어 요소