그루비(Groovy) 튜토리얼 4 – 정규식(Regular Expression) 기본

그루비(Groovy) 튜토리얼 4 - 정규식(Regular Expression) 기본

2008.3.25 translation & editing by gilbird

원문: http://groovy.codehaus.org/Tutorial+4+-+Regular+expressions+basics

정규식(Regular Expression)

정규식은 텍스트 처리의 스위스 아미 나이프라고 할 수 있다. 정규식으로 문자열의 패턴을 찾아 추출할 수 있다. 가장 간단한 정규식의 예로는 문자와 숫자가 있다. 그리고 가장 간단한 식으로는 ==~를 사용한 정규식이 있다. 예를 들어 ‘potatoe’와 문자열이 일치하는지 보려면 다음과 같이 한다.

“potatoe” ==~ /potatoe/

groovyConsole에 위 식을 입력하여 실행하면 true를 리턴할 것이다. 몇가지 주목할 만한 점이 있다. 첫번째는 ==와 유사한 ==~ 연산자인데 정확히 일치하는 패턴에 대해서만 일치한다. 두번째는 정규식이 /로 둘러쌓아서 그루비에게 일반 문자열이 아닌 정규식임을 알린다.

정확한 철자가 일치하는지 체크하길 원하는데 ‘e’ 다음에 ‘?’를 추가하면 e는 선택사항(있어도 되고 없어도 됨)이다. 다음 정규식은 true다.

“potatoe” ==~ /potatoe?/

정확한 철자도 일치한다.

“potato” ==~ /potatoe?/

다음은 앞의 두경우 모두 해당되지 않으며 일치하지 않는다.

“motato” ==~ /potatoe?/

다음은 정규식을 가진 간단한 대수식(boolean expression)을 정의하는 방법이다. 정규식을 테스트하는 메서드를 만들어보자. 예를 들어 Pete Winsniewski의 성과의 일치여부를 체크하는 코드를 만들어 보자.

def checkSpelling(spellingAttempt, spellingRegularExpression) {        if (spellingAttempt ==~ spellingRegularExpression) {               println(“Congratulations, you spelled it correctly.”)         } else {               println(“Sorry, try again.”)        }}theRegularExpression = /Wisniewski/checkSpelling(“Wisniewski”, theRegularExpression)checkSpelling(“Wisnewski”, theRegularExpression)

위 코드에서는 몇가지 특이한 점이 있다. 첫번째로 함수를 정의하였다(실제로는 메서드지만 두 단어를 혼용해서 쓰겠다). 함수는 클로저와 유사한 코드의 집합이다. 클로저는 익명일 수 있지만 함수는 항상 이름을 가지고 있다. 한번 정의하면 나중에 계속 쓸 수 있다.

checkSpelling 함수에서 if문은 주어진 파라메터 spellingAttempt와 spellingRegularExpression의 패턴이 일치하는지 ==~ 연산자로 검사한다.

checkSpelling 함수를 이용하여 이름의 중앙에 ‘w’를 가지지 않은 문자열을 찾고 싶은 경우 다음과 같이 할 수 있다:

theRegularExpression = /Wisniew?ski/checkSpelling(“Wisniewski”, theRegularExpression)checkSpelling(“Wisnieski”, theRegularExpression)checkSpelling(“Wisniewewski”, theRegularExpression)

checkSpelling함수의 spellingRegularExpression 인자로 들어간 theRegularExpression값에 ? 한개는 바로 앞의 문자(‘w’)는 선택사항이라는 것이다. 이 코드를 spellingAttempt에 다른 w의 위치에 다른 철자를 넣어 두 가지 철자법 ‘Wisniewski’와 ‘Wisnieski’만 일치함을 증명해보자.

?는 정규식에서 특별한 의미임을 기억하기 바란다.

단어 중앙의 “ie” 순서가 바뀌어도 일치한 것으로 보이도록 해보자.

theRegularExpression = /Wisn(ie|ei)w?ski/checkSpelling(“Wisniewski”, theRegularExpression)checkSpelling(“Wisnieski”, theRegularExpression)checkSpelling(“Wisniewewski”, theRegularExpression)

위의 정규식으로 철자에 대해서 이야기 해보자. ‘Wisniewski”, “Wisneiwski”, “Wisnieski”, Wisneiski” 4가지 철자가 일치하는 것으로 나온다. 막대 문자 ‘|’는 왼쪽이나 오른쪽 항목(위의 경우에는 “ie”나 “ei”)이 수락 가능한 것임을 말한다.  괄호는 간단하게 관심 부분의 시작과 끝임을 표시한다.

정규식 중 흥미로운 특징중의 하나로 문자집합을 지정하여 일치를 허용하는 방법이 있는데 꺽쇄괄호[]를 사용한다.

다음과 같이 Pete의 성에 다양한 철자법 오류를 시도해 보자.

theRegularExpression = /Wis[abcd]?niewski/ // ‘a’, ‘b’, ‘c’ , ‘d’ 중의 하나 혹은 없음
theRegularExpression = /Wis[a-zA-Z]niewski/ // 소문자나 대문자가 필요함
theRegularExpression = /Wis[^abcd]niewski/ // ‘a’, ‘b’, ‘c’ , ‘d’ 가 아닌 문자가 필요함

마지막 문장의 [] 처음에 있는 ^는 꺽쇄괄호 안에 지정한 문자를 제외한 나머지 문자를 말한다.   

연산자

이제 정규식의 동작 방식을 이해했을 것이다. 다음은 유용한 연산자들에 대한 내용이다.

정규식 연산자

a? a가 0개 혹은 1개 발생하면 일치 ‘a’ 나 빈 문자열
a* a가 0 혹은 그 이상 발생할 때 일치 빈 문자열이나 ‘a’, ‘aa’, ‘aaa’, 등
a+ a가 1번 이상 발생하면 일치‘a’, ‘aa’, ‘aaa’, 등
a|b a 나 b면 일치‘a’ 나 ‘b’
. 한개의 문자면 일치 ‘a’, ‘q’, ‘l’, ‘_’, ‘+’, 등
[woeirjsd] 지정한 문자들 중 하나 이면 일치 ‘w’, ‘o’, ‘e’, ‘i’, ‘r’, ‘j’, ‘s’, ‘d’
[1-9] 범위 안의 문자면 일치 ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’
[^13579] 지정한 문자 이외의 문자이면 일치 짝수 혹은 문자
(ie) 수식을 묶음 (다른 연산자와 사용하기 위함) ‘ie’
^a 줄의 맨 처음에 a가 있으면 일치‘a’
a$ 줄의 맨 끝에 a가 있으면 일치 ‘a’

 

?와 같이 위에 나와 있는 연산자를 실제 문자로 사용하려면 문자 앞에 ‘\’를 넣으면 된다.

// ?가 제일 끝에만 나오는 문장은 true
“How tall is Angelina Jolie?” ==~ /[^\?]+\?/

위 예는 가독성이 떨어진다. (PERL에서는 이렇게 많이 사용하는데 “write only” 언어로 여겨지는 이유 중의 하나이다.) 

Leave a Reply