본문 바로가기

C#/정규 표현식

C#에서 정규 표현식으로 일치하는 부분 문자열을 모두 찾고 여러 가지 처리하는 방법 (LINQ 적용, 찾은 부분 문자열의 일부분만 추출)

1. 일치하는 문자열을 모두 찾고 그 결과에 LINQ를 적용하는 방법

 

 

Regex 클래스에 있는 Matches 메서드를 사용하면 패턴에 일치하는 모든 문자열을 찾을 수 있다.

 

Matches 메서드의 반환값의 형인 MatchCollection 형은 IEnumerable<T> 인터페이스를 가지고 있지 않기 때문에 이 상태로는 LINQ를 사용할 수 없다.

 

사용할 수 있게 하려면 Cast<T> 메서드를 사용해 IEnumerable<Match>로 변환해야 한다.

 

Cast<T> 메서드는 <> 안에 구체적인 형 (이번 예제에서는 Match)을 지정해 컬렉션을 IEnumerable<T> (이번 예제에서는 IEnumerable<Match>)로 변환할 수 있다.

var text = “private List<string> results = new List<string>();”;
var matches = Regex.Matches(text, @”\b[a-z]+\b”)    //소문자만으로 구성된 단어 모두 찾기
                            .Cast<Match>()                     //LINQ를 사용할 수 있도록 IEnumerable<Match>로 변환
                            .OrderBy(x => x.Length);          //길이가 짧은 순서로 나열 (LINQ 사용)
foreach (Match match in matches)
{
    Console.WriteLine(“Index={0}, Length={1}, Value={2}”, match.Index, match.Length, match.Value);
}

 

결과

Index=31, Length=3, Value=new
Index=13, Length=6, Value=string
Index=40, Length=6, Value=string
Index=0, Length=7, Value=private
Index=21, Length=7, Value=results

예제에서 사용한 정규표현식 @”\b[a-z]+\b”에서 \b의 역할

정규 표현식 문자열 안에 있는 ‘\b’는 단어의 경계를 나타낸다.

 

@”[a-z]+”라고 지정하면 “List”의 “ist” 부분과도 일치하게 되므로 의도한대로 동작하지 않게된다.

 

 

 

 

 

 

2. 일치하는 문자열을 모두 찾고 찾은 부분 문자열의 일부만 추출하는 방법

 

“C#에는 «값형»과 «참조형»이라는 두 가지의 형이 존재합니다.”

 

위 문자열에서 «»로 묶인 “값형”과 “참조형”이라는 문자열을 꺼낸다고 가정하자.

 

이 처리에서 귀찮은 점은 일치시키고 싶은 것이 ‘«값형»’이나 ‘«참조형»’이고 꺼내고 싶은 것은 “값형”과 “참조형”이라는 점이다.

 

검색한 후에 문자열의 앞뒤에 있는 «»를 삭제하도록 구현해도 처리할 수 있지만 정규 표현식의 그룹화 기능을 사용하면 그런 장황한 코드를 작성하지 않아도 «»로 묶인 문자열을 구할 수 있다.

var text = “C#에는 «값형»과 «참조형»이라는 두 가지의 형이 존재합니다.”;
var matches = Regex.Matches(text, @”«([^«»]+)»”);
foreach (Match match in matches)
{
    Console.WriteLine(“<{0}>”, match.Groups[1]);
}

 

결과

<값형>
<참조형>

예제에서 사용한 정규표현식 @”«([^«»]+)»”

정확한 결과를 얻을 수 있는 정규 표현식까지 발전하는 과정

1. @”«.+»”

한 문자 이상의 임의의 문자가 «»로 묶여 있다는 것을 표현한 것

 

이렇게 하면 맞는 것 같지만 정규 표현식은 최대한 긴 문자열과 일치시키려고 하기 때문에 “«값형»과 «참조형»”이라는 문자열이 일치하게 된다.

2. @”«[^«»]+»”

‘«’이나 ‘»’와 일치하지 않도록 점(.)이 있는 부분을 «» 이외의 것을 나타내는 “[^«»]”로 바꾼다.

 

이렇게 하면 ‘«값형»’이라는 문자열과 일치한다.

3. @”«([^«»]+)»”

구하고 싶은 것은 ‘«’나 ‘»’를 제외한 ‘값형’이라는 문자열이다.

이 작업을 가능하게 하는 것이 그룹화라는 기능이다.

구하려는 문자열을 괄호 ()로 묶어서 그룹화하면 일치한 문자열 안에서 ()안에 있는 문자열만을 꺼낼 수 있다.

 

Match 객체에 있는 Group 속성을 참조하면 그룹화한 문자열을 꺼낼 수 있다.

 

정규 표현식 안에 여러 개의 그룹화가 있을 경우에는 Groups[1], Groups[2], Groups[3]이라고 기술하여 각각에 일치한 문자열을 꺼낼 수 있다.