본문 바로가기

C#/정규 표현식

C#에서 정규 표현식 '최단 일치 수량자'를 사용해 패턴에 매칭되는 것 중 가장 짧은 것을 일치시키는 방법

정규 표현식의 최장 일치의 원칙

정규 표현식에는 최장 일치의 원칙이 있다.

 

‘최장 일치’란 패턴에 매칭되는 것 중에서 가장 긴 것을 일치시킨다는 의미이다.

var text = “<person><name>홍길동<\name><age>18<\age><\person>”;
var pattern = @”<.+>”;
var matches = Regex.Matches(text, pattern);
foreach (Match m in matches)
    Console.WriteLine(“‘{0}’”, m.Value);

 

“<.+>”이라는 정규 표현식을 이용했는데 최장 일치의 원칙이 작용해서

“<person>”이 아니라

“<person><name>홍길동<\name><age>18<\age><\person>” 문자열 전체가 일치한다.

 

최장 일치의 원칙이 적용된다는 사실을 인지하고 있는 것이 정규 표현식을 쓸 때 주의해야 할 사항이다.

 

이러한 사실을 고려하지 않고 정규 표현식을 대충 쓰면 생각하지도 못한 버그를 심어놓게된다.

 

 

정규 표현식을 조작해서 최단으로 일치시키는 방법

 

만일 앞서 나온 문자열에 대해 “person”, “name”, “age”라는 세 단어를 구하려고 한다면 정규 표현식을 조작해서 다음과 같은 코드를 작성해야한다.

var text = “<person><name>홍길동<\name><age>18<\age><\person>”;
var pattern = @”<(\w[^>]+)>”;
var matches = Regex.Matches(text, pattern);

 

@”<(\w[^>]+)>”

최단으로 일치시키는 정규 표현식 분석

\w

단어에 사용되는 임의 문자와 일치한다.

이렇게 지정하면 “<\name>”이나 “<!-- 주석 -->” 과 같은 문자열을 제외할 수 있다. (알파벳이나 숫자만 해당하므로)

 

[.과 \w 차이]

     임의의 한 문자 (문자의 종류 가리지 않음). 단, \ 는 넣을 수 없음

\w   알파벳이나 숫자

[^>]+

두 번째 문자 이후에 해당되는 문자 클래스를 지정

[^>]는 > 외의 문자를 나타낸다.

이렇게 하면 “<person><name>”처럼 도중에 >가 포함된 부분 문자열에 일치하지 않게 할 수 있다.

(...)

괄호로 그룹화

() 자체는 검색 대상이 되는 문자가 아니고 () 안에 있는 문자가 검색 대상이 된다.

Match 객체에 있는 Groups 속성을 참조하면 이렇게 그룹화한 부분에 일치한 결과를 참조할 수 있다.

 

 

 

 

정규 표현식 최단 일치 수량자를 사용해 최단으로 일치시키는 방법

 

 

위에서 정규 표현식을 조작해서 목적에 맞는 부분 문자열과 일치시키는 방법을 설명했는데 최단 일치의 수량자를 사용하는 방법도 있다.

 

일반적인 수량자 뒤에 ?를 붙이면 최단 일치로 지정한 것이 된다.

 

*?  최대한 적게 반복하는 것을 지정한다.

+?  한 번 이상이며 최대한 적게 반복하는 것을 지정한다.

 

최단 일치의 수량자를 사용하면 정규 표현식은

@”<(\w[^>]+)>”
이었던 것을

@”<(\w+?)>”
라고 쓸 수 있게된다.

 

최단 일치 수량자를 사용해 다음에 나오는 문자열에서 <p>와 </p>로 묶인 구분

var text = “<p>가나다라마</p><p>바사아자차</p>”;
var pattern = @”<p>(.*?)</p>”;
var matches = Regex.Matches(text, pattern);
foreach (Match m in matches)
    Console.WriteLine(“‘{0}’”, m.Groups[1].Value);
‘가나다라마’
‘바사아자차’