
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/ theRegularExpression = /Wis[a-zA-Z]niewski/ theRegularExpression = /Wis[^abcd]niewski/
마지막 문장의 [] 처음에 있는 ^는 꺽쇄괄호 안에 지정한 문자를 제외한 나머지 문자를 말한다.
연산자
이제 정규식의 동작 방식을 이해했을 것이다. 다음은 유용한 연산자들에 대한 내용이다.
정규식 연산자
| 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' |
?와 같이 위에 나와 있는 연산자를 실제 문자로 사용하려면 문자 앞에 '\'를 넣으면 된다.
"How tall is Angelina Jolie?" ==~ /[^\?]+\?/
위 예는 가독성이 떨어진다. (PERL에서는 이렇게 많이 사용하는데 "write only" 언어로 여겨지는 이유 중의 하나이다.)