Home Full Site
Regex - Group 클래스

Regular Expression의 표현식 중에 ( ) 로 표현되는 Group 표현식이 있는데, 이는 특히 유용한 기능을 제공한다. 이 그룹 표현식은 괄호안에 있는 문자열들을 찾아내어 Match 클래스 객체의 Match.Groups 속성에 결과를 넣게 된다. Match.Groups 속성은 GroupCollection 클래스 객체로서 복수의 Group 클래스 객체를 갖는다.
아래 Ex1은 아파트 혹은 APT라는 문자열이 있는 부분의 문자열 위치 정보를 Match.Groups에 저장하고, 이를 출력해 보이는 예제이다. 여기서 한가지 주의할 점은 Match.Groups는 Match.Groups[1]부터 각 그룹의 결과가 저장된다는 것이다. 패턴이 발견되지 않았을 때에도 Match.Groups[0]는 존재하여 여기에 Group.Success = false를 저장하여 실패를 표현한다.
Ex2 예제는 보다 실용적인 예로써 HTML 페이지에서 List 요소값을 모두 찾아내는 예이다.
Ex3 예제는 전화번호의 패턴을 찾아내는 예로써 지역번호와 나머지 전화번호를 분리하여 2개의 그룹에 넣는 예를 보여주고 있다.


예제

// Ex1
string str = "강남빌라 역삼아파트 서초APT";
Regex regex = new Regex(@"(아파트|APT)");
MatchCollection mc = regex.Matches(str);
foreach (Match m in mc)
{
    // (Captured) Group은 1부터
    Group g = m.Groups[1];
    Debug.WriteLine("{0}:{1}", g.Index, g.Value);
}

// Ex2
string str = "<ul><li>홈페이지</li><li>주문메뉴</li></ul>";
Regex regex = new Regex(@"<li>(\w+)</li>");
MatchCollection mc = regex.Matches(str);
foreach (Match m in mc)
{
    Group g = m.Groups[1];
    Debug.WriteLine("{0}:{1}", g.Index, g.Value);                
}

// Ex3
string str = "02-632-5432; 032-645-7361";
Regex regex = new Regex(@"(\d+)-(\d+-\d+)");
MatchCollection mc = regex.Matches(str);
foreach (Match m in mc)
{
    for (int i = 1; i < m.Groups.Count; i++)
    {
        Group g = m.Groups[i];
        Debug.WriteLine("{0}:{1}", g.Index, g.Value);
    }
}



Regex - Named Group

위의 섹션에서 그룹에 대해 설명하였는데, 위에서 복수의 그룹들은 인덱스를 통해서만 접근할 수 있었다. 그런데, Regular Expression에서는 그룹에 이름을 붙여서 사용하는 것(Named Group)이 가능한데, 이는 매우 유용하게 사용될 수 있다. 즉, 각 그훕별로 이름을 붙이면, 여러 그룹들을 사용할 경우 차후에 이름을 통해 그룹 객체를 엑세스할 수 있게되어, 코드를 쓰거나 읽는 것이 쉬워진다. 아래 Ex1 예제는 전화번호를 2개의 그룹으로 나누고, 첫부분을 areaNo로 명명하고 나머지는 phoneNo롤 명명한 후, 이를 이후 코드에 사용하고 있다. 위의 첫번째 섹션 Ex3과 비교했을 때, 코드를 읽기가 훨씬 쉽다는 것을 알 수 있다.
Ex2 예제는 웹페이지에 있는 연결 링크(a href) 정보를 Regular Expression을 써서 쉽게 읽어내는 코드이다.


예제

// Ex1. named group (?<name> )
string str = "02-632-5432; 032-645-7361";
Regex regex = new Regex(@"(?<areaNo>\d+)-(?<phoneNo>\d+-\d+)");
MatchCollection mc = regex.Matches(str);
foreach (Match m in mc)
{                            
    string area = m.Groups["areaNo"].Value;
    string phone = m.Groups["phoneNo"].Value;
    Debug.WriteLine("({0}) {1}", area, phone);
}

// Ex2
string str = "<div><a href='www.sqlmgmt.com'>SQL Tools</a></div>";
string patt = @"<a[^>]*href\s*=\s*[""']?(?<href>[^""'>]+)[""']?";
Match m = Regex.Match(str, patt);
Group g = m.Groups["href"];
Debug.WriteLine(g.Value);  



Regex을 이용한 문자열 치환

Regex 클래스에서 자주 사용되는 메서드에는 특정 패턴을 찾아내는 Match() / Matches(), 특정 패턴을 기준으로 문자열을 분리하는 Split(), 그리고 찾아낸 문자열을 다른 문자열로 치환하는 Replace() 등이 있다. (이러한 메서드들은 객체를 통한 인스턴스 메서드 혹은 Regex 클래스로 직접 호출되는 Static 메서드 모두에서 호출될 수 있다) Replace() 메서드는 지정된 특정 패턴으로 문자열을 찾아낸 후 이를 다시 파라미터에 지정된 치환 값으로 변경하는 기능을 한다. 예를 들어, 아래 Ex1은 문자열에서 공백이 들어가는 부분을 찾아내어 모두 삭제하는 코드이다. 앞부분 공백을 지우는 ^\s+ 패턴과 뒷부분 공백을 지우는 \s+$ 패턴을 함께 | (OR) 로 묵어 사용할 수 있다.
Ex2는 ###-###-#### 로 표현된 전화번호를 (###) ###-#### 형식으로 변경하는 예제이다. 이 예제에서 보이듯이 기존 패턴의 내용을 그룹명으로 지정하면 이를 ${그룹명} 형식으로 치환 표현식에서 지정할 수 있다.


예제

// Ex1. 앞 공백 제거
string str = "   서울시 강남구 역삼동 강남아파트 1  ";
string patten = @"^\s+";
// 앞뒤 공백 모두 제거시:  @"^\s+|\s+$";

Regex regex = new Regex(patten);
string s = regex.Replace(str, "");
Debug.WriteLine(s);

// Ex2
string str = "02-632-5432; 032-645-7361";
string patten = @"(?<areaNo>\d+)-(?<phoneNo>\d+-\d+)";
Regex regex = new Regex(patten);
string s = regex.Replace(str, @"(${areaNo}) ${phoneNo}");
Debug.WriteLine(s);



© csharpstudy.com