전체 페이지뷰

2016년 12월 1일 목요일

Regular expression 4

Greedy quantifier와 Reluctant quantifier

/".+"/와 같은 quantifier를 적용할 때 어떤 일이 일어나는가를 보겠습니다.
영어 "Hello"와 스페인어 "Hola"와 같은 경우 모두 위의 식에 부합합니다. 
그러나 실제로 /".+"/가 "Hello"와 같은 의미인가 하면 그렇지는 않습니다.

Python 정규식에서 쓰이는 quantifier는 두가지로 분류할 수 있는데 그것은,
greedy와 non-greedy(reluctant) quantifier입니다

Greedy는 탐욕스러운...이라는 뜻에서 알 수 있듯이 가능한 많은 결과를 
매칭하려는 속성입니다.

Non-greedy 는 ? 메타캐릭터를 사용하여(예를 들면 ??, *?, +?와 같이) 
매칭의 수를 제한하려는(가능한 적은 결과를 매칭하려는) 속성을 말합니다.

(사실 Java와 .NET에서만 쓰이는 세번째 속성이 있는데 그것은 Possessive 속성입니다.
추가의 + 기호를 쓰는 방법인데(?+, *+, ++) 여기서는 논하지 않습니다.

English-->"Hello",-->Spanish-->"Hola".
라는 문자열에서 /".+"/를 적용하면 어디가 될까요? 마침표로 둘러싸인 모든 문자를 뜻하므로 Hello, Hola 두개가 될 것 같지만 사실 Hello",-->Spanish-->"Hola 가 됩니다. 중간의 마침표도 모두 문자로 간주하고 최대한 끝 마침표까지 다 매칭시키므로 greedy 하다고 합니다.

그럼 /".+?"를 적용하면 어떻게 될까요? ?가 하나 더 들어가 있습니다. 이 경우에 매칭은 Hello와 Hola가 되어 가능한 작은 범위만 포함시킵니다.




Boundary Matcher

지금까지 우리는 텍스트 내부의 작은 표현을 매칭시키는 법을 알아봤습니다. 이제부터는 줄 전체를 매칭해보려 합니다.그러기 위해서는 시작 부위와 끝나는 부위를 알아야 하므로 경계를 제한해줄 필요가 있습니다.
다음은 boundary matcher의 종류입니다.
이 boundary matcher는 다른 언어에서는 다른ㄴ 의미로 쓰이는 경우도 있으니 참고하길 바랍니다.

그럼 이제, 예를 좀 살펴 보겠습니다.

/^Name:/    
line의 처음에(^) Name: 이라는 리터럴이 오는 경우

/^Name:[\sa-zA-Z]+$/
line의 처음에(^) Name:이라는 리터럴이 오고 그 뒤에 공백(\s)이나 소문자영어(a-z)나 대문자영어(A-Z) 중에 하나가([ ]) 하나 이상(+)나타나고 문장이 끝나는($) 경우

/\bhello\b/
문자 경계부(\b)로 시작해서 hello가 오고 다시  문자경계부\(b)가 나오는 경우.
다시 말해 "helloed"나 "othello"와 같이 문자 중간에 나타나는 경우가 아닌 순수한 "hello"만을 뜻합니다.


지금까지 이론적인 부분에서 정규식에 대해 알아봤습니다.
다음부터는 Python에서 re 모듈을 써서 실제로 적용하는 법을 살펴보겠습니다.

댓글 없음:

댓글 쓰기