다음을 통해 공유


수량자

업데이트: 2008년 7월

수량자는 이전 요소(문자, 그룹 또는 문자 클래스)의 인스턴스가 입력에 몇 개 있어야 일치가 검색되는지를 지정합니다.

.NET Framework 정규식의 수량자

다음 표에서는 .NET Framework 정규식에서 지원되는 수량자를 보여 줍니다. 수량 n 및 m은 정수 상수입니다. greedy 및 lazy 수량자 사이의 차이점에 대한 설명은 표 아래에 있는 "Greedy 및 Lazy 수량자" 단원을 참조하십시오.

수량자

설명

*

이전 요소를 0개 이상 찾습니다. 이는 {0,}와 같습니다. *는 greedy 수량자이며 해당 non-greedy 수량자는 *?입니다.

예를 들어 정규식 \b91*9*\b는 단어 경계 뒤에 나오는 숫자 9를 찾습니다. 9 뒤에는 숫자 1이 0개 이상 나올 수 있고, 그 뒤에는 숫자 9가 0개 이상 나올 수 있습니다. 다음 예제에서는 이 정규식을 보여 줍니다. 입력 문자열에 있는 숫자 9개 중 5개가 패턴과 일치하고 4개(95, 929, 9129 및 9919)는 일치하지 않습니다.

Dim pattern As String = "\b91*9*\b"
Dim input As String = "99 95 919 929 9119 9219 999 9919 91119"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
' '99' found at position 0.
' '919' found at position 6.
' '9119' found at position 14.
' '999' found at position 24.
' '91119' found at position 33.
string pattern = "\b91*9*\b";
string input = "99 95 919 929 9119 9219 999 9919 91119";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
// The example displays the following output:
// '99' found at position 0.
// '919' found at position 6.
// '9119' found at position 14.
// '999' found at position 24.
// '91119' found at position 33.

+

이전 요소를 1개 이상 찾습니다. 이 옵션은 {1,}와 같습니다. +는 greedy 수량자이며 해당 non-greedy 수량자는 +?입니다.

예를 들어 정규식 \ba(n)+\w*?\b는 문자 a로 시작하고 뒤에 문자 n이 한 개 이상 나오는 전체 단어를 찾습니다. 다음 예제에서는 이 정규식을 보여 줍니다. 이 정규식은 단어 an, annual, announcement 및 antique와 일치하지만 autumn 및 all과는 일치하지 않습니다.

Dim pattern As String = "\ba(n)+\w*?\b"
Dim input As String = "Autumn is a great time for an annual announcement to all antique collectors."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
' 'an' found at position 27.
' 'annual' found at position 30.
' 'announcement' found at position 37.
' 'antique' found at position 57.
string pattern = @"\ba(n)+\w*?\b";
string input = "Autumn is a great time for an annual announcement to all antique collectors.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
// The example displays the following output:
// 'an' found at position 27.
// 'annual' found at position 30.
// 'announcement' found at position 37.
// 'antique' found at position 57.

?

이전 요소를 0개 또는 1개 찾습니다. 이 옵션은 {0,1}와 같습니다. ?는 greedy 수량자이며 해당 non-greedy 수량자는 ??입니다.

예를 들어 정규식 \ban?\b는 문자 a로 시작하고 뒤에 문자 n이 0개 또는 1개 나오는 전체 단어를 찾습니다. 즉, 단어 a 및 an과 일치합니다. 다음 예제에서는 이 정규식을 보여 줍니다.

Dim pattern As String = "\ban?\b"
Dim input As String = "An amiable animal with a large snount and an animated nose."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
' 'An' found at position 0.
' 'a' found at position 23.
' 'an' found at position 42.
string pattern = @"\ban?\b";
string input = "An amiable animal with a large snount and an animated nose.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
// The example displays the following output:
// 'An' found at position 0.
// 'a' found at position 23.
// 'an' found at position 42.

{n}

이전 요소를 정확히 n개 찾습니다. {n}은 greedy 수량자이며 해당 non-greedy 수량자는 {n}?입니다.

예를 들어 정규식 \b\d+\,\d{3}\b는 단어 경계 뒤에 숫자가 하나 이상 나오고 그 뒤에 숫자 세 개가 나온 후 단어 경계가 나오는 경우를 찾습니다. 다음 예제에서는 이 정규식을 보여 줍니다.

Dim pattern As String = "\b\d+\,\d{3}\b"
Dim input As String = "Sales totaled 103,524 million in January, " + _
"106,971 million in February, but only " + _
"943 million in March."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
' '103,524' found at position 14.
' '106,971' found at position 45.
string pattern = @"\b\d+\,\d{3}\b";
string input = "Sales totaled 103,524 million in January, " +
"106,971 million in February, but only " +
"943 million in March.";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
// The example displays the following output:
// '103,524' found at position 14.
// '106,971' found at position 45.

{n,}

이전 요소를 최소한 n개 이상 찾습니다. {n,}는 greedy 수량자이며 해당 non-greedy 수량자는 {n}?입니다.

예를 들어 정규식 \b\d{2,}\b\D+는 단어 경계 뒤에 최소한 숫자 2개가 나오고 그 뒤에 단어 경계가 나온 후 숫자가 아닌 문자가 나오는 경우를 찾습니다. 다음 예제에서는 이 정규식을 보여 줍니다. 7 days라는 구는 숫자를 하나만 포함하므로 이 정규식과 일치하지 않지만 10 weeks 및 300 years라는 구는 정규식과 일치합니다.

Dim pattern As String = "\b\d{2,}\b\D+"
Dim input As String = "7 days, 10 weeks, 300 years"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
' '10 weeks, ' found at position 8.
' '300 years' found at position 18.
string pattern = @"\b\d{2,}\b\D+";
string input = "7 days, 10 weeks, 300 years";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
// The example displays the following output:
// '10 weeks, ' found at position 8.
// '300 years' found at position 18.

{n,m}

이전 요소를 n개 이상 m개 이하로 찾습니다. {n,m}은 greedy 수량자이며 해당 non-greedy 수량자는 {n,m}?입니다.

예를 들어 정규식 (00\s){2,4}는 두 개의 0이 2-4회 나온 후 공백이 나오는 경우를 찾습니다. 다음 예제에서는 이 정규식을 보여 줍니다. 입력 문자열의 마지막 부분에는 이 패턴이 최대값인 4회가 아닌 5회 포함되어 있습니다. 그러나 이 부분 문자열의 처음 부분(공백과 다섯 번째 0 쌍)은 정규식 패턴과 일치합니다.

Dim pattern As String = "(00\s){2,4}"
Dim input As String = "0x00 FF 00 00 18 17 FF 00 00 00 21 00 00 00 00 00"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
' '00 00 ' found at position 8.
' '00 00 00 ' found at position 23.
' '00 00 00 00 ' found at position 35.
string pattern = @"(00\s){2,4}";
string input = "0x00 FF 00 00 18 17 FF 00 00 00 21 00 00 00 00 00";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
// The example displays the following output:
// '00 00 ' found at position 8.
// '00 00 00 ' found at position 23.
// '00 00 00 00 ' found at position 35.

*?

이전 요소를 0개 이상 가능한 한 적은 개수로 찾습니다. 이는 lazy 수량자이며 해당 greedy 수량자는 *입니다.

예를 들어 정규식 \b\w*?oo\w*?\b는 문자열 oo가 들어 있는 모든 단어와 일치합니다. 다음 예제에서는 이 정규식을 보여 줍니다.

Dim pattern As String = "\b\w*?oo\w*?\b"
Dim input As String = "woof root root rob oof woo woe"
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
' 'woof' found at position 0.
' 'root' found at position 5.
' 'root' found at position 10.
' 'oof' found at position 19.
' 'woo' found at position 23.
string pattern = @"\b\w*?oo\w*?\b";
string input = "woof root root rob oof woo woe";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
// The example displays the following output:
// 'woof' found at position 0.
// 'root' found at position 5.
// 'root' found at position 10.
// 'oof' found at position 19.
// 'woo' found at position 23.

+?

이전 요소를 1개 이상 가능한 한 적은 개수로 찾습니다. 이는 lazy 수량자이며 해당 greedy 수량자는 +입니다.

예를 들어 정규식 \b\w+?\b는 단어 경계로 구분된 하나 이상의 문자를 찾습니다. 다음 예제에서는 이 정규식을 보여 줍니다.

Dim pattern As String = "\b\w+?\b"
Dim input As String = "Aa Bb Cc Dd Ee Ff"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
' 'Aa' found at position 0.
' 'Bb' found at position 3.
' 'Cc' found at position 6.
' 'Dd' found at position 9.
' 'Ee' found at position 12.
' 'Ff' found at position 15.
string pattern = @"\b\w+?\b";
string input = "Aa Bb Cc Dd Ee Ff";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
// The example displays the following output:
// 'Aa' found at position 0.
// 'Bb' found at position 3.
// 'Cc' found at position 6.
// 'Dd' found at position 9.
// 'Ee' found at position 12.
// 'Ff' found at position 15.

??

이전 요소를 가능한 한 적은 개수로 0개 또는 1개 찾습니다. 이는 lazy 수량자이며 해당 greedy 수량자는 ?입니다.

예를 들어 정규식 ^(\s)*(System.)??Console.Write(Line)??\(??은 문자열 Console.Write 또는 Console.WriteLine을 찾습니다. 문자열에서 Console 앞에 System.이 포함될 수도 있고 뒤에 여는 괄호가 나올 수도 있습니다. 문자열은 줄의 맨 앞에 있어야 하지만 앞에 공백이 나올 수는 있습니다. 다음 예제에서는 이 정규식을 보여 줍니다.

Dim pattern As String = "^(\s)*(System.)??Console.Write(Line)??\(??"
Dim input As String = "System.Console.WriteLine(""Hello!"")" + vbCrLf + _
"Console.Write(""Hello!"")" + vbCrLf + _
"Console.WriteLine(""Hello!"")" + vbCrLf + _
"Console.ReadLine()" + vbCrLf + _
" Console.WriteLine"
For Each match As Match In Regex.Matches(input, pattern, _
RegexOptions.IgnorePatternWhitespace Or RegexOptions.IgnoreCase Or RegexOptions.MultiLine)
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
' 'System.Console.Write' found at position 0.
' 'Console.Write' found at position 36.
' 'Console.Write' found at position 61.
' ' Console.Write' found at position 110.
string pattern = @"^(\s)*(System.)??Console.Write(Line)??\(??";
string input = "System.Console.WriteLine(\"Hello!\")\n" +
"Console.Write(\"Hello!\")\n" +
"Console.WriteLine(\"Hello!\")\n" +
"Console.ReadLine()\n" +
" Console.WriteLine";
foreach (Match match in Regex.Matches(input, pattern,
RegexOptions.IgnorePatternWhitespace |
RegexOptions.IgnoreCase |
RegexOptions.Multiline))
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
// The example displays the following output:
// 'System.Console.Write' found at position 0.
// 'Console.Write' found at position 36.
// 'Console.Write' found at position 61.
// ' Console.Write' found at position 110.

{n}?

이전 요소를 정확히 n개 찾습니다. 이는 lazy 수량자이며 해당 greedy 수량자는 {n}+입니다.

예를 들어 정규식 \b(\w{3,}?\.){2}?\w{3,}?\b는 정확히 두 개의 문자 집합 뒤에 단어 경계의 마침표가 나오는 경우를 찾습니다. 그 뒤에 다른 문자 집합과 단어 경계가 나옵니다. 이 정규식은 웹 사이트의 주소를 식별합니다. 다음 예제에서는 이 정규식을 보여 줍니다. 이 정규식은 www.microsoft.com 및 mdsn.microsoft.com과 일치하지만 mywebsite 또는 mycompany.com과는 일치하지 않습니다.

Dim pattern As String = "\b(\w{3,}?\.){2}?\w{3,}?\b"
Dim input As String = "www.microsoft.com msdn.microsoft.com mywebsite mycompany.com"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
' 'www.microsoft.com' found at position 0.
' 'msdn.microsoft.com' found at position 18.
string pattern = @"\b(\w{3,}?\.){2}?\w{3,}?\b";
string input = "www.microsoft.com msdn.microsoft.com mywebsite mycompany.com";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
// The example displays the following output:
// 'www.microsoft.com' found at position 0.
// 'msdn.microsoft.com' found at position 18.

{n,}?

이전 요소를 최소한 n개 이상 가능한 한 적은 개수로 찾습니다. 이는 lazy 수량자이며 해당 greedy 수량자는 {n,}입니다.

{n}? 수량자에 대한 예제를 참조하십시오. 해당 예제의 정규식에서는 {n,} 수량자를 사용하여 최소한 3개의 문자 뒤에 마침표가 나오는 문자열을 찾습니다.

{n,m}?

이전 요소를 n에서 m개 찾으며, 가능한 한 적은 개수로 찾습니다. 이는 lazy 수량자이며 해당 greedy 수량자는 {n,m}입니다.

예를 들어 정규식 \b[A-Z](\w*?\s*?){1,10}[.!?]는 단어가 1-10개 들어 있는 문장을 찾습니다. 즉, 단어 경계 뒤에 대문자가 나오고 그 뒤에 0개 이상의 단어 문자와 선택적인 공백 문자가 1-10회 반복된 후 마침표, 느낌표 또는 물음표로 종료되는 경우를 찾습니다. 다음 예제에서는 이 정규식을 보여 줍니다. 이 정규식은 입력 문자열에서 단어가 18개 들어 있는 문장 하나를 제외하고 모든 문장과 일치합니다.

Dim pattern As String = "\b[A-Z](\w*?\s*?){1,10}[.!?]"
Dim input As String = "Hi. I am writing a short note. Its purpose is " + _
"to test a regular expression that attempts to find " + _
"sentences with ten or fewer words. Most sentences " + _
"in this note are short."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
' 'Hi.' found at position 0.
' 'I am writing a short note.' found at position 4.
' 'Most sentences in this note are short.' found at position 132.
string pattern = @"\b[A-Z](\w*?\s*?){1,10}[.!?]";
string input = "Hi. I am writing a short note. Its purpose is " +
"to test a regular expression that attempts to find " +
"sentences with ten or fewer words. Most sentences " +
"in this note are short.";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
// The example displays the following output:
// 'Hi.' found at position 0.
// 'I am writing a short note.' found at position 4.
// 'Most sentences in this note are short.' found at position 132.

Greedy 및 Lazy 수량자

여러 수량자에는 두 가지 버전이 있습니다.

  • greedy 버전

    greedy 수량자는 요소를 찾을 때 최대한 많은 횟수를 적용합니다.

  • non-greedy 또는 lazy 버전

    non-greedy 수량자는 요소를 찾을 때 최대한 적은 횟수를 적용합니다.

두 버전의 차이점을 쉽게 이해할 수 있도록 신용 카드 번호와 같은 숫자 문자열에서 마지막 네 숫자를 추출하는 매우 단순한 정규식을 예로 들어 봅니다. * greedy 수량자를 사용하는 정규식 버전은 \b.*([0-9]{4})\b입니다. 그러나 숫자가 두 개 들어 있는 문자열을 지정하면 다음 예제와 같이 두 번째 숫자의 마지막 네 숫자만 표시됩니다.

Dim greedyPattern As String = "\b.*([0-9]{4})\b"
Dim input1 As String = "1112223333 3992991999"
For Each match As Match In Regex.Matches(input1, greedypattern)
   Console.WriteLine("Account ending in ******{0}.", match.Groups(1).Value)
Next
' The example displays the following output:
'       Account ending in ******1999.
string greedyPattern = @"\b.*([0-9]{4})\b";
string input1 = "1112223333 3992991999";
foreach (Match match in Regex.Matches(input1, greedyPattern))
   Console.WriteLine("Account ending in ******{0}.", match.Groups[1].Value);

// The example displays the following output:
//       Account ending in ******1999.

이는 올바른 동작이 아닙니다. * 수량자는 전체 문자열에서 이전 요소를 최대한 많이 찾으므로 첫 번째 숫자가 정규식과 일치하지 않고 문자열의 끝 부분에서 일치 항목이 검색됩니다.

그러나 *? lazy 수량자를 사용하는 동일한 정규식은 다음 예제와 같이 올바른 동작을 보여 줍니다.

Dim lazyPattern As String = "\b.*?([0-9]{4})\b"
Dim input2 As String = "1112223333 3992991999"
For Each match As Match In Regex.Matches(input2, lazypattern)
   Console.WriteLine("Account ending in ******{0}.", match.Groups(1).Value)
Next     
' The example displays the following output:
'       Account ending in ******3333.
'       Account ending in ******1999.
string lazyPattern = @"\b.*?([0-9]{4})\b";
string input2 = "1112223333 3992991999";
foreach (Match match in Regex.Matches(input2, lazyPattern))
   Console.WriteLine("Account ending in ******{0}.", match.Groups[1].Value);

// The example displays the following output:
//       Account ending in ******3333.
//       Account ending in ******1999.

대부분의 경우에는 greedy 수량자와 lazy 수량자를 사용한 정규식에서 동일한 일치 항목을 반환합니다. 서로 다른 결과가 반환되는 가장 일반적인 경우는 모든 문자를 찾는 마침표( . ) 메타문자가 사용된 경우입니다.

참고 항목

기타 리소스

정규식 언어 요소

변경 기록

날짜

변경 내용

이유

2008년 7월

광범위하게 수정되었습니다.

콘텐츠 버그 수정