본문 바로가기
Python/점프 투 파이썬

정규 표현식 (2)

by k-mozzi 2021. 9. 14.
반응형
Preface

 

지난 포스팅에 이어 정규 표현식을 공부하며 이런 생각이 들었다.

 

'정규 표현식은 길고 복잡한 코드를 보다 짧고 간결하게 만들어주기 위해 사용하는 것인데, 이를  본격적으로 사용하기 시작하면 오히려 코드가 복잡해져 가독성이 떨어지는 것 같다.'

 

물론 내가 아직 정규 표현식에 익숙치 않아 이렇게 느낄 수도 있겠지만, 아래 예제들만 보아도 여러 문자가 혼합되어 있어 한 눈에 알아보기 무척 힘들며, 무엇보다 파이썬의 장점인 직관성을 해친다고 생각한다.

 

숙련된 개발자들은 정규 표현식을 사용하여 길게 작성된 코드를 쉽게 알아볼 수 있을까?


 

1. 메타 문자

 

import re

p = re.compile('Crow|Servo')
m = p.match('CrowHello')
print(m, '\n')
# | 메타 문자는 or과 동일한 의미로 사용된다.


print(re.search('^Life', 'Life is too short'))
print(re.search('^Life', 'My Life'), '\n')
# ^ 메타 문자는 문자열의 맨 처음과 일치함을 의미한다.


print(re.search('short$', 'Life is too short'))
print(re.search('short$', 'Life is too short, you need python'), '\n')
# $는 문자열의 끝과 매치함을 의미한다.


# \A는 문자열의 처음과 매치됨을 의미한다.
# re.MULTILINE 옵션을 사용할 경우 ^은 각 줄의 문자열의 처음과 매치되지만 \A는 줄과 상관없이 전체 문자열의 처음하고만 매치된다.


# \Z는 문자열의 끝과 매치됨을 의미한다.
# re.MULTILINE 옵션을 사용할 경우 $ 메타 문자와는 달리 전체 문자열의 끝과 매치된다.


p = re.compile(r'\bclass\b')
print(p.search('no class at all'))
print(p.search('the declassified algorithm'), '\n')
# \b는 단어 구분자(Word boundary)이다. 보통 단어는 whitespace 에 의해 구분된다.
# \b는 파이썬 리터럴 규칙에 의하면 백스페이스(BackSpace)를 의미하므로 기호 r을 반드시 붙여 주어야 한다.


p = re.compile(r'\Bclass\B')
print(p.search('no class at all'))
print(p.search('the declassified algorithm'))
# \B 메타 문자는 whitespace 로 구분된 단어가 아닌 경우에만 매치된다.

 


 

2. 그루핑

 

import re

p = re.compile('(ABC)+')
m = p.search('ABCABCABC OK?')
print(m, '\n')
# 그룹을 만들어 주는 메타 문자는 ( )이다.
# 특정 문자열이 계속해서 반복되는지 조사하거나
# 매치된 문자열 중에서 특정 부분의 문자열만 뽑아내기 위해 사용한다.


p = re.compile(r'(\w+)\s+(\d+[-]\d+[-]\d+)')
m = p.search('Kim 010-1234-5678')
print(m.group(2), '\n')
# group(0)	매치된 전체 문자열
# group(1)	첫 번째 그룹에 해당되는 문자열
# group(2)	두 번째 그룹에 해당되는 문자열
# group(n)	n 번째 그룹에 해당되는 문자열
# 그룹 중첩 사용 가능!


p = re.compile(r'(\b\w+)\s+\1')
m = p.search('Paris in the the rain')
print(m.group(), '\n')
# 그루핑된 문자열 재참조하기
# \1은 정규식의 그룹 중 첫 번째 그룹을 가리킨다.


p = re.compile(r'(?P<name>\w+)\s+(?P<num>\d+[-]\d+[-]\d+)')
m = p.search('Kim 010-1234-5678')
print(m.group('name'))
print(m.group('num'), '\n')
# 그룹에 이름을 지어 주려면 (?P<그룹명>...)과 같은 확장 구문을 사용해야 한다.


p = re.compile('.+(?=:)')
m = p.search('http://google.com')
print(m.group(), '\n')
# 긍정형 전방 탐색(?=...) : ...에 해당되는 정규식과 매치되어야 하며
# 조건이 통과되어도 문자열이 소비되지 않는다.
# 부정형 전방 탐색(?!...) : ...에 해당되는 정규식과 매치되지 않아야 하며
# 조건이 통과되어도 문자열이 소비되지 않는다.


p = re.compile('blue|white|red')
print(p.sub('color', 'blue socks and red shoes', count=2), '\n')
# sub 메서드의 첫 번째 매개변수는 "바꿀 문자열(replacement)"이 되고, 두 번째 매개변수는 "대상 문자열"이 된다.
# 세 번째 매개변수로 count 값을 넘기면 바꾸는 횟수를 제어할 수 있다.
# subn 역시 sub 와 동일한 기능을 하지만 반환 결과를 튜플로 돌려준다는 차이가 있다.


p = re.compile(r'(?P<name>\w+)\s+(?P<phone>(\d+)[-]\d+[-]\d+)')
print(p.sub('\g<phone> \g<name>', 'Kim 010-1234-1234'))
# \g<그룹이름>을 사용하면 정규식의 문자열 순서를 바꿀 수 있다.
# 그룹이름 대신 참조 번호를 사용해도 같은 결과를 돌려준다.


# non-greedy 문자인 ?는 *?, +?, ??, {m,n}?와 같이 사용되며,
# 가능한 한 가장 최소한의 반복을 수행하도록 도와주는 역할을 한다.

 

 

 

 

 

출처 : https://wikidocs.net/4309

 

07-3 강력한 정규 표현식의 세계로

이제 07-2에서 배우지 않은 몇몇 메타 문자의 의미를 살펴보고 그룹(Group)을 만드는 법, 전방 탐색 등 더욱 강력한 정규 표현식에 대해서 살펴보자. [TOC] # ...

wikidocs.net

 

728x90
반응형

'Python > 점프 투 파이썬' 카테고리의 다른 글

종합문제 (2)  (0) 2021.09.17
종합문제 (1)  (0) 2021.09.16
정규 표현식 (1)  (0) 2021.09.13
간단한 코드 작성  (0) 2021.09.12
5장 연습문제  (0) 2021.09.09

댓글