System.Text.RegularExpressions.Regex 클래스

이 문서에서는 이 API에 대한 참조 설명서에 대한 추가 설명서를 제공합니다.

클래스는 Regex .를 나타냅니다. NET의 정규식 엔진입니다. 이 클래스를 사용하여 다음을 수행할 수 있습니다.

  • 많은 양의 텍스트를 신속하게 구문 분석하여 특정 문자 패턴을 찾습니다.
  • 텍스트 하위 문자열을 추출, 편집, 바꾸기 또는 삭제합니다.
  • 추출된 문자열을 컬렉션에 추가하여 보고서를 생성합니다.

참고 항목

문자열이 특정 정규식 패턴을 준수하는지 여부를 확인하여 문자열의 유효성을 검사하려는 경우 클래스를 System.Configuration.RegexStringValidator 사용할 수 있습니다.

정규식을 사용하려면 정규식 언어로 문서화된 구문인 빠른 참조를 사용하여 텍스트 스트림에서 식별하려는 패턴을 정의합니다. 다음으로 필요에 따라 개체를 인스턴스화할 Regex 수 있습니다. 마지막으로 정규식 패턴과 일치하는 텍스트를 바꾸거나 패턴 일치를 식별하는 등의 일부 작업을 수행하는 메서드를 호출합니다.

정규식 언어 에 대한 자세한 내용은 다음 브로셔 중 하나를 빠르게 참조 하거나 다운로드하여 인쇄하는 정규식 언어를 참조하세요.

word(.docx) 형식의 빠른 참조(pdf) 형식(.pdf) 형식의 빠른 참조

Regex 및 문자열 메서드

System.String 클래스에는 텍스트와 패턴 일치를 수행하는 데 사용할 수 있는 몇 가지 검색 및 비교 메서드가 포함되어 있습니다. 예를 들어 String.Contains, String.EndsWithString.StartsWith 메서드는 문자열 인스턴스에 지정된 부분 문자열String.IndexOf이 포함되어 있는지 여부를 결정하고 , , String.LastIndexOfString.IndexOfAnyString.LastIndexOfAny 메서드는 문자열에서 지정된 부분 문자열의 시작 위치를 반환합니다. 특정 문자열을 검색할 System.String 때 클래스의 메서드를 사용합니다. 문자열에서 Regex 특정 패턴을 검색할 때 클래스를 사용합니다. 자세한 내용 및 예제는 .NET 정규식을 참조 하세요.

정적 메서드와 인스턴스 메서드 비교

정규식 패턴을 정의한 후 다음 두 가지 방법 중 하나를 사용하여 정규식 엔진에 제공할 수 있습니다.

  • 정규식을 나타내는 개체를 인스턴스화 Regex 합니다. 이렇게 하려면 정규식 패턴을 Regex 생성자에 전달합니다. Regex 개체는 변경할 수 없습니다. 정규식을 사용하여 개체를 Regex 인스턴스화하면 해당 개체의 정규식을 변경할 수 없습니다.

  • (Visual Basic에서) Regex 메서드로 검색할 staticShared 정규식과 텍스트를 모두 제공합니다. 이렇게 하면 개체를 명시적으로 만들지 않고 정규식을 사용할 수 있습니다 Regex .

모든 Regex 패턴 식별 메서드에는 정적 오버로드와 인스턴스 오버로드가 모두 포함됩니다.

정규식 엔진은 패턴을 사용하려면 먼저 특정 패턴을 컴파일해야 합니다. 개체는 변경할 수 있으므로 Regex 클래스 생성자 또는 정적 메서드를 호출할 때 Regex 발생하는 일회성 프로시저입니다. 단일 정규식을 반복적으로 컴파일할 필요가 없도록 정규식 엔진은 정적 메서드 호출에 사용되는 컴파일된 정규식을 캐시합니다. 따라서 정규식 패턴 일치 메서드는 정적 및 인스턴스 메서드에 대해 비슷한 성능을 제공합니다. 그러나 캐싱은 다음 두 경우의 성능에 부정적인 영향을 줄 수 있습니다.

  • 많은 수의 정규식과 함께 정적 메서드 호출을 사용하는 경우 기본적으로 정규식 엔진은 가장 최근에 사용한 15개의 정적 정규식을 캐시합니다. 15 개 이상의 정적 정규식을 사용 하는 애플리케이션에서 일부 정규식을 컴파일해야 합니다. 이 다시 컴파일을 방지하려면 속성을 늘릴 Regex.CacheSize 수 있습니다.

  • 이전에 컴파일된 정규식을 사용하여 새 Regex 개체를 인스턴스화하는 경우 예를 들어 다음 코드는 텍스트 스트림에서 중복된 단어를 찾는 정규식을 정의합니다. 이 예제에서는 단일 정규식을 사용하지만 새 개체를 Regex 인스턴스화하여 각 텍스트 줄을 처리합니다. 이렇게 하면 루프의 각 반복과 함께 정규식이 다시 컴파일됩니다.

    StreamReader sr = new StreamReader(filename);
    string input;
    string pattern = @"\b(\w+)\s\1\b";
    while (sr.Peek() >= 0)
    {
       input = sr.ReadLine();
       Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
       MatchCollection matches = rgx.Matches(input);
       if (matches.Count > 0)
       {
          Console.WriteLine("{0} ({1} matches):", input, matches.Count);
          foreach (Match match in matches)
             Console.WriteLine("   " + match.Value);
       }
    }
    sr.Close();
    
    Dim sr As New StreamReader(filename)
    Dim input As String
    Dim pattern As String = "\b(\w+)\s\1\b"
    Do While sr.Peek() >= 0
       input = sr.ReadLine()
       Dim rgx As New Regex(pattern, RegexOptions.IgnoreCase)
       Dim matches As MatchCollection = rgx.Matches(input)
       If matches.Count > 0 Then
          Console.WriteLine("{0} ({1} matches):", input, matches.Count)
          For Each match As Match In matches
             Console.WriteLine("   " + match.Value)
          Next   
       End If
    Loop
    sr.Close()
    

    다시 컴파일을 방지하려면 다음 다시 작성된 예제와 같이 필요한 모든 코드에서 액세스할 수 있는 단일 Regex 개체를 인스턴스화해야 합니다.

    StreamReader sr = new StreamReader(filename);
    string input;
    string pattern = @"\b(\w+)\s\1\b";
    Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
    
    while (sr.Peek() >= 0)
    {
       input = sr.ReadLine();
       MatchCollection matches = rgx.Matches(input);
       if (matches.Count > 0)
       {
          Console.WriteLine("{0} ({1} matches):", input, matches.Count);
          foreach (Match match in matches)
             Console.WriteLine("   " + match.Value);
       }
    }
    sr.Close();
    
    Dim sr As New StreamReader(filename)
    Dim input As String
    Dim pattern As String = "\b(\w+)\s\1\b"
    Dim rgx As New Regex(pattern, RegexOptions.IgnoreCase)
    Do While sr.Peek() >= 0
       input = sr.ReadLine()
       Dim matches As MatchCollection = rgx.Matches(input)
       If matches.Count > 0 Then
          Console.WriteLine("{0} ({1} matches):", input, matches.Count)
          For Each match As Match In matches
             Console.WriteLine("   " + match.Value)
          Next   
       End If
    Loop
    sr.Close()
    

정규식 작업 수행

개체를 Regex 인스턴스화하고 해당 메서드를 호출하거나 정적 메서드 Regex 를 호출하기로 결정하든 클래스는 다음과 같은 패턴 일치 기능을 제공합니다.

  • 일치 항목의 유효성 검사입니다. 메서드를 IsMatch 호출하여 일치 항목이 있는지 여부를 확인합니다.

  • 단일 일치 항목을 검색합니다. 메서드를 Match 호출하여 문자열 또는 문자열의 일부에서 첫 번째 일치 항목을 나타내는 개체를 검색 Match 합니다. 메서드를 호출하여 후속 일치 항목을 검색할 Match.NextMatch 수 있습니다.

  • 모든 일치 항목을 검색합니다. 메서드를 Matches 호출하여 문자열 또는 문자열의 일부에서 찾은 모든 일치 항목을 나타내는 개체를 검색 System.Text.RegularExpressions.MatchCollection 합니다.

  • 일치하는 텍스트를 대체합니다. 일치하는 텍스트를 바꾸기 위해 메서드를 호출 Replace 합니다. 대체 텍스트는 정규식으로 정의할 수도 있습니다. 또한 일부 Replace 메서드에는 대체 텍스트를 프로그래밍 방식으로 정의할 수 있는 매개 변수가 포함 MatchEvaluator 됩니다.

  • 입력 문자열의 일부에서 형성된 문자열 배열을 만듭니다. 메서드를 Split 호출하여 정규식으로 정의된 위치에서 입력 문자열을 분할합니다.

패턴 일치 메서드 Regex 외에도 클래스에는 다음과 같은 몇 가지 특수 용도의 메서드가 포함됩니다.

  • 메서드는 Escape 정규식 또는 입력 문자열에서 정규식 연산자로 해석될 수 있는 모든 문자를 이스케이프합니다.
  • 이 메서드는 이러한 이 Unescape 스케이프 문자를 제거합니다.
  • 메서드는 CompileToAssembly 미리 정의된 정규식을 포함하는 어셈블리를 만듭니다. .NET에는 네임스페이스에서 이러한 특수 용도 어셈블리의 예제가 System.Web.RegularExpressions 포함되어 있습니다.

제한 시간 값 정의

.NET은 패턴 일치에서 상당한 성능과 유연성을 제공하는 완전한 기능을 갖춘 정규식 언어를 지원합니다. 그러나 성능과 유연성은 성능 저하의 위험이 있습니다. 제대로 수행되지 않는 정규식은 놀라울 정도로 쉽게 만들 수 있습니다. 경우에 따라 과도한 역추적을 사용하는 정규식 작업은 정규식 패턴과 거의 일치하는 텍스트를 처리할 때 응답을 중지하는 것처럼 보일 수 있습니다. .NET 정규식 엔진에 대한 자세한 내용은 정규식 동작의 세부 정보를 참조 하세요. 과도한 역추적에 대한 자세한 내용은 역추적을 참조 하세요.

.NET Framework 4.5부터 정규식 일치에 대한 제한 시간 간격을 정의하여 과도한 역추적을 제한할 수 있습니다. 정규식 패턴 및 입력 텍스트에 따라 실행 시간이 지정된 제한 시간 간격을 초과할 수 있지만 지정된 제한 시간 간격보다 역추적하는 데 더 많은 시간을 소비하지는 않습니다. 정규식 엔진의 시간이 초과되면 예외가 RegexMatchTimeoutException throw됩니다. 대부분의 경우 정규식 엔진이 정규식 패턴과 거의 일치하는 텍스트를 일치시키려고 시도하여 처리 능력을 낭비하지 못하게 합니다. 그러나 시간 제한 간격이 너무 낮게 설정되었거나 현재 컴퓨터 부하로 인해 전반적인 성능 저하가 발생했음을 나타낼 수도 있습니다.

예외를 처리하는 방법은 예외의 원인에 따라 달라집니다. 시간 제한 간격이 너무 낮게 설정되거나 과도한 컴퓨터 로드로 인해 예외가 발생하는 경우 제한 시간 간격을 늘리고 일치 작업을 다시 시도할 수 있습니다. 정규식이 과도한 역추적을 사용하므로 예외가 발생하는 경우 일치 항목이 없다고 가정할 수 있으며, 필요에 따라 정규식 패턴을 수정하는 데 도움이 되는 정보를 기록할 수 있습니다.

정규식 개체를 인스턴스화할 때 생성자를 호출 Regex(String, RegexOptions, TimeSpan) 하여 제한 시간 간격을 설정할 수 있습니다. 정적 메서드의 경우 매개 변수가 있는 일치하는 메서드의 오버로드를 호출하여 제한 시간 간격을 matchTimeout 설정할 수 있습니다. 제한 시간 값을 명시적으로 설정하지 않으면 기본 제한 시간 값이 다음과 같이 결정됩니다.

  • 애플리케이션 수준 시간 제한을 사용 하 여 값 하나 있습니다. 속성에 값의 문자열 표현 TimeSpan 을 할당하는 메서드를 호출 AppDomain.SetData 하여 애플리케이션 전체 제한 시간 값을 REGEX_DEFAULT_MATCH_TIMEOUT 설정합니다.
  • 값을 사용 하 여 InfiniteMatchTimeout없는 애플리케이션 수준 시간 제한 값이 설정 된 경우.

Important

모든 정규식 패턴 일치 작업에서 제한 시간 값을 설정하는 것이 좋습니다. 자세한 내용은 정규식에 대한 모범 사례를 참조 하세요.

예제

다음 예제에서는 정규식을 사용하여 문자열에서 반복되는 단어 발생에 대해 검사. 정규식 \b(?<word>\w+)\s+(\k<word>)\b 은 다음 표와 같이 해석할 수 있습니다.

패턴 설명
\b 단어 경계에서 일치를 시작합니다.
(?<word>\w+) 하나 이상의 단어 문자를 단어 경계까지 찾습니다. 캡처된 이 그룹의 word이름을 지정합니다.
\s+ 하나 이상의 공백 문자를 찾습니다.
(\k<word>) 이름이 word지정된 캡처된 그룹과 일치합니다.
\b 단어 경계를 찾습니다.
using System;
using System.Text.RegularExpressions;

public class Test
{
    public static void Main ()
    {
        // Define a regular expression for repeated words.
        Regex rx = new Regex(@"\b(?<word>\w+)\s+(\k<word>)\b",
          RegexOptions.Compiled | RegexOptions.IgnoreCase);

        // Define a test string.
        string text = "The the quick brown fox  fox jumps over the lazy dog dog.";

        // Find matches.
        MatchCollection matches = rx.Matches(text);

        // Report the number of matches found.
        Console.WriteLine("{0} matches found in:\n   {1}",
                          matches.Count,
                          text);

        // Report on each match.
        foreach (Match match in matches)
        {
            GroupCollection groups = match.Groups;
            Console.WriteLine("'{0}' repeated at positions {1} and {2}",
                              groups["word"].Value,
                              groups[0].Index,
                              groups[1].Index);
        }
    }
}

// The example produces the following output to the console:
//       3 matches found in:
//          The the quick brown fox  fox jumps over the lazy dog dog.
//       'The' repeated at positions 0 and 4
//       'fox' repeated at positions 20 and 25
//       'dog' repeated at positions 49 and 53
Imports System.Text.RegularExpressions

Public Module Test

    Public Sub Main()
        ' Define a regular expression for repeated words.
        Dim rx As New Regex("\b(?<word>\w+)\s+(\k<word>)\b", _
               RegexOptions.Compiled Or RegexOptions.IgnoreCase)

        ' Define a test string.        
        Dim text As String = "The the quick brown fox  fox jumps over the lazy dog dog."
        
        ' Find matches.
        Dim matches As MatchCollection = rx.Matches(text)

        ' Report the number of matches found.
        Console.WriteLine("{0} matches found in:", matches.Count)
        Console.WriteLine("   {0}", text)

        ' Report on each match.
        For Each match As Match In matches
            Dim groups As GroupCollection = match.Groups
            Console.WriteLine("'{0}' repeated at positions {1} and {2}", _ 
                              groups.Item("word").Value, _
                              groups.Item(0).Index, _
                              groups.Item(1).Index)
        Next
    End Sub
End Module
' The example produces the following output to the console:
'       3 matches found in:
'          The the quick brown fox  fox jumps over the lazy dog dog.
'       'The' repeated at positions 0 and 4
'       'fox' repeated at positions 20 and 25
'       'dog' repeated at positions 49 and 53

다음 예제에서는 정규식을 사용하여 문자열이 통화 값을 나타내는지 아니면 통화 값을 나타내는 올바른 형식인지를 검사 보여 줍니다. 이 경우 정규식은 en-US 문화권에 NumberFormatInfo.CurrencyDecimalSeparator대한 , CurrencyDecimalDigits, NumberFormatInfo.CurrencySymbolNumberFormatInfo.NegativeSignNumberFormatInfo.PositiveSign 속성에서 동적으로 빌드됩니다. 결과 정규식은 .입니다 ^\s*[\+-]?\s?\$?\s?(\d*\.?\d{2}?){1}$. 이 정규식은 다음 표와 같이 해석할 수 있습니다.

패턴 설명
^ 문자열의 시작 부분에서 시작합니다.
\s* 0개 이상의 공백 문자가 일치하는지 확인합니다.
[\+-]? 양수 기호 또는 음수 기호가 0개 또는 1번 일치하는지 확인합니다.
\s? 0번 이상 나오는 공백 문자를 찾습니다.
\$? 달러 기호가 0개 또는 1번 일치하는지 확인합니다.
\s? 0번 이상 나오는 공백 문자를 찾습니다.
\d* 0번 이상 나오는 10진수를 찾습니다.
\.? 0 또는 10진수 기호와 일치합니다.
(\d{2})? 그룹 1 캡처: 10진수 2자리를 0개 또는 1회 일치시킵니다.
(\d*\.?(\d{2})?){1} 소수점 기호로 구분된 정수 및 소수 자릿수의 패턴을 한 번 이상 일치시킵니다.
$ 문자열의 끝과 일치합니다.

이 경우 정규식은 유효한 통화 문자열에 그룹 구분 기호가 없고 소수 자릿수 또는 지정된 문화권의 CurrencyDecimalDigits 속성에 정의된 소수 자릿수가 없다고 가정합니다.

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

public class Example
{
    public static void Main()
    {
        // Get the en-US NumberFormatInfo object to build the regular 
        // expression pattern dynamically.
        NumberFormatInfo nfi = CultureInfo.GetCultureInfo("en-US").NumberFormat;

        // Define the regular expression pattern.
        string pattern;
        pattern = @"^\s*[";
        // Get the positive and negative sign symbols.
        pattern += Regex.Escape(nfi.PositiveSign + nfi.NegativeSign) + @"]?\s?";
        // Get the currency symbol.
        pattern += Regex.Escape(nfi.CurrencySymbol) + @"?\s?";
        // Add integral digits to the pattern.
        pattern += @"(\d*";
        // Add the decimal separator.
        pattern += Regex.Escape(nfi.CurrencyDecimalSeparator) + "?";
        // Add the fractional digits.
        pattern += @"(\d{";
        // Determine the number of fractional digits in currency values.
        pattern += nfi.CurrencyDecimalDigits.ToString() + "})?){1}$";

        Console.WriteLine($"Pattern is {pattern}\n");

        Regex rgx = new Regex(pattern);

        // Define some test strings.
        string[] tests = { "-42", "19.99", "0.001", "100 USD",
                         ".34", "0.34", "1,052.21", "$10.62",
                         "+1.43", "-$0.23" };

        // Check each test string against the regular expression.
        foreach (string test in tests)
        {
            if (rgx.IsMatch(test))
                Console.WriteLine($"{test} is a currency value.");
            else
                Console.WriteLine($"{test} is not a currency value.");
        }
    }
}
// The example displays the following output:
//       Pattern is ^\s*[\+-]?\s?\$?\s?(\d*\.?(\d{2})?){1}$
//
//       -42 is a currency value.
//       19.99 is a currency value.
//       0.001 is not a currency value.
//       100 USD is not a currency value.
//       .34 is a currency value.
//       0.34 is a currency value.
//       1,052.21 is not a currency value.
//       $10.62 is a currency value.
//       +1.43 is a currency value.
//       -$0.23 is a currency value.
Imports System.Globalization
Imports System.Text.RegularExpressions

Public Module Example
   Public Sub Main()
      ' Get the current NumberFormatInfo object to build the regular 
      ' expression pattern dynamically.
      Dim nfi As NumberFormatInfo = CultureInfo.GetCultureInfo("en-US").NumberFormat

      ' Define the regular expression pattern.
      Dim pattern As String 
      pattern = "^\s*["
      ' Get the positive and negative sign symbols.
      pattern += Regex.Escape(nfi.PositiveSign + nfi.NegativeSign) + "]?\s?"
      ' Get the currency symbol.
      pattern += Regex.Escape(nfi.CurrencySymbol) + "?\s?"
      ' Add integral digits to the pattern.
      pattern += "(\d*"
      ' Add the decimal separator.
      pattern += Regex.Escape(nfi.CurrencyDecimalSeparator) + "?"
      ' Add the fractional digits.
      pattern += "(\d{"
      ' Determine the number of fractional digits in currency values.
      pattern += nfi.CurrencyDecimalDigits.ToString() + "})?){1}$"
      
      Console.WriteLine("Pattern is {0}", pattern)
      Console.WriteLine()
      
      Dim rgx As New Regex(pattern)

      ' Define some test strings.
      Dim tests() As String = {"-42", "19.99", "0.001", "100 USD", _
                               ".34", "0.34", "1,052.21", "$10.62", _
                               "+1.43", "-$0.23" }

      ' Check each test string against the regular expression.
      For Each test As String In tests
         If rgx.IsMatch(test) Then
            Console.WriteLine("{0} is a currency value.", test)
         Else
            Console.WriteLine("{0} is not a currency value.", test)
         End If
      Next
   End Sub
End Module
' The example displays the following output:
'       Pattern is ^\s*[\+-]?\s?\$?\s?(\d*\.?(\d{2})?){1}$
'
'       -42 is a currency value.
'       19.99 is a currency value.
'       0.001 is not a currency value.
'       100 USD is not a currency value.
'       .34 is a currency value.
'       0.34 is a currency value.
'       1,052.21 is not a currency value.
'       $10.62 is a currency value.
'       +1.43 is a currency value.
'       -$0.23 is a currency value.

이 예제의 정규식은 동적으로 작성되므로 디자인 타임에 정규식 엔진에서 정규식 언어 연산자로 지정된 문화권의 통화 기호, 10진수 기호 또는 양수 및 음수 기호를 잘못 해석할 수 있는지 여부를 알 수 없습니다. 잘못된 해석을 방지하기 위해 예제에서는 동적으로 생성된 각 문자열을 메서드에 Escape 전달합니다.