Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

정규식(Regular Expressions)

텍스트 처리에 있어서 정규식은 스위스 군용 칼과도 같습니다. 정규식을 이용하면 문자열에서 특정 *패턴*을 찾아내고 뽑아낼 수 있습니다. 정규식의 가장 단순한 예는 문자와 숫자로 구성된 문자열입니다. 그리고 정규식을 사용하는 가장 간단한 표현식은 *==~* 연산자를 사용하는 것입니다. So for example to match Dan Quayle's spelling of 'potato':

groovyConsole에 위 코드를 입력하고 실행하면 true로 평가될 것입니다. 두 가지 주목할 점이 있습니다. 첫째, ==~ 연산자는 ==와 비슷한데 정확한 문자열 일치를 검사하는 것이 아니라 정규식 패턴을 검사합니다. 둘째, 정규식이 / 로 둘러쌓여 있다는 사실입니다. 슬래시 기호는 그 안에 있는 문자열이 보통 String이 아니라 정규식이라는 사실을 알려줍니다.

올바른 철자인 "potato"와도 일치되길 원한다면 'e' 다음에 '?'를 붙여서 'e'가 생략가능하다는 점을 명시할 수 있습니다. 따라서 아래 코드는 여전히 true로 평가됩니다:

그리고 올바른 철자 또한 true 입니다:

하지만 그 외의 문자열은 false가 됩니다:

위 예제들이 바로 정규식을 이용하여 Boolean 표현식을 정의하는 방법들입니다. 여기서 조금 더 나아가 보겠습니다. 정규식을 테스트하는 메서드를 정의하겠습니다. Pete Wisniewski의 성을 검사하는 코드입니다:

두 가지 새로운 개념이 등장했습니다. 첫째, 함수를 정의했습니다. 사실은 메서드이지만, 함수와 메서드를 같은 뜻으로 간주하고 사용하도록 하겠습니다. 함수란 코드 모음인데 클로저와 비슷합니다. 하지만 함수는 항상 이름을 갖습니다. 반면 클로저는 익명일 수도 있지요. 일단 함수를 정의했으면 나중에 언제든 불러쓸 수 있습니다.

이 함수에서는 spellingAttempt가 정규식과 일치하는지를 비교하기 위해 *==~* 연산자를 쓰고 있습니다.

여기서 더 나아가보겠습니다. 이름 중간에 'w'가 없어도 되도록 고쳐봅시다:

spellingRegularExpression에 추가된 *?* 문자가 의미하는 것은 그 앞에 있는 문자('w')가 생략가능하다는 것입니다. *spellingAttempt* 변수에 여러 다른 값들을 입력해서 위 코드를 실행해보면 단지 두 가지 철자("Wisniewski"와 "Wisnieski")만이 수용된다는 점을 알 수 있습니다. (checkSpelling의 정의는 고칠 필요가 없습니다)

*?* 문자는 정규식에서 특별한 의미를 가지는 문자 중 하나입니다. 모든 구두점 문자들에 특별한 의미가 있다고 보아도 됩니다.

이제 중간에 있는 'ie'가 뒤집어져도 상관없도록 만들어봅시다. 다음 코드를 보세요:

다시 여러 철자를 대입해보세요. 이제 네가지 철자 - "Wisniewski", "Wisneiwski", "Wisnieski", "Wisneiski" - 가 통과할 것입니다. 바(|) 문자는 그 문자 좌,우 중 한가지를 수용할 수 있음을 의미합니다. 위 경우엔 'ie' 혹은 'ei' 입니다. 괄호 표시는 바 문자가 적용되는 구간을 나타내줍니다.

다음으로 소개할 흥미로운 기능은 여러 개의 문자 중 어느 것이든 받아드려지도록 하는 것입니다. *[ ]* 기호를 사용하면 됩니다. 다음 코드를 실험해보세요:

위 예제에서 마지막 정규식은 설명이 필요할 것 같습니다. 꺽쇄괄호의 첫 문자가 *^* 이면 괄호 안에 있는 문자들을 제외한 어떤 문제도 허용된다는 뜻입니다.

연산자

So now that you have a sense for how regular expressions work, here are the operators that you will find helpful, and what they do:

Regular Expression Operators

| a? | matches 0 or 1 occurrence of *a* | 'a' or empty string |
| a
* | matches 0 or more occurrences of *a* | empty string or 'a', 'aa', 'aaa', etc |
| a
+ | matches 1 or more occurrences of *a* | 'a', 'aa', 'aaa', etc |
| a|b | match *a* or *b* | 'a' or 'b' - |
| . | match any single character | 'a', 'q', 'l', '_', '+', etc |
| [woeirjsd] | match any of the named characters | 'w', 'o', 'e', 'i', 'r', 'j', 's', 'd' |
| [1-9] | match any of the characters in the range | '1', '2', '3', '4', '5', '6', '7', '8', '9' |
| [^13579] | match any characters not named | even digits, or any other character |
| (ie) | group an expression (for use with other operators) | 'ie' |
| ^a | match an *a* at the beginning of a line | 'a' |
| a$ | match an *a* at the end of a line | 'a' |
There are a couple of other things you should know. If you want to use one of the operators above to mean the actual character, like you want to match a question mark, you need to put a '\' in front of it. For example:

This is your first really ugly regular expression. (The frequent use of these in PERL is one of the reasons it is considered a "write only" language). By the way, google knows how tall [she is|http://www.google.com/search?hl=en&q=how+tall+is+angelina+jolie&btnG=Google+Search]. The only way to understand expressions like this is to pick it apart:
| / | [^?] | + | ? | /  |
| begin expression | any character other than '?' | more than one of those | a question mark | end expression |
So the use of the \ in front of the ? makes it refer to an actual question mark.

  • No labels