* 이 포스트는 "파이썬 프로그래밍으로 지루한 작업 자동화하기" 의 내용을 참조해서 작성하였습니다.
* 파이썬 3.3을 기준으로 작성하였습니다.
정규표현식으로 텍스트 패턴 검색
정규식 객체 만들기
re 패키지를 import 합니다.
>>> import re
정규표현식을 나타내는 문자열 값을 re.compile()에 전달하여 Rebex 패턴 객체 (혹은 Regex 객체)를 생성합니다.
>>> phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
(참고로 미국 전화번호 포맷은 000-000-0000 형식입니다.)
Regex 객체를 이용한 패턴 검색
위에서 생성한 패턴 객체에 search 매써드를 이용해서 match 객체를 돌려 받습니다.
>>> mo = phoneNumRegex.search('My number is 212-555-1234.')
Match 객체에 group 매써드를 이용해서 결과를 확인합니다.
>>> print (mo.group())
212-555-1234
정규표현식을 사용한 더 많은 패턴 검색
괄호로 묶기
패턴 중의 일부를 분리해서 사용하는 경우 (전화번호에서 지역 코드를 나머지 번호로부터 분리하고 싶은 경우)
>>> phoneNumRegex = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)')
>>> mo = phoneNumRegex.search('My number is 212-555-1234.')
>>> print (mo.group(1))
212
>>> print (mo.group(2))
555-1234
>>> print (mo.group(0))
212-555-1234
>>> print (mo.group())
212-555-1234
>>> print (mo.groups())
(212, 555-1234)
파이프로 여러 그룹 검색하기
'|' 글자를 파이프라고 합니다.
여러 가지 표현 중 하나만 일치해도 되는 곳에 사용 (or)
처음으로 일치하는 텍스트가 Match 객체로 반환됩니다.
>>> testRegex = re.compile(r'AAA|BBB')
>>> mo1 = testRegex.search('AAA and BBB')
>>> mo1.group()
'AAA'
>>> mo2 = testRegex.search('BBB and AAA')
>>> mo2.group()
'BBB'
물음표와 선택적 검색
해당 부분이 없거나 한 번만 나타나는 경우
>>> testRegex = re.compile(r'Super(wo)?man')
>>> mo1 = testRegex.search('The world of Superman')
>>> mo1.group()
'Superman'
>>> mo2 = testRegex.search('The world of Superwoman')
>>> mo2.group()
'Superwoman'
* 및 + 를 이용한 선택적 검색
* 표시는 0개 또는 그 이상과 일치를 의미
+ 표시는 1개 또는 그 이상과 일치를 의미
>>> testRegex = re.compile(r'Super(wo)*man')
>>> mo1 = testRegex.search('The world of Superman')
>>> mo1.group()
'Superman'
>>> mo2 = testRegex.search('The world of Superwoman')
>>> mo2.group()
'Superwoman'
>>> mo3 = testRegex.search('The world of Superwowowoman')
>>> mo3.group()
'Superwowowoman'
>>> testRegex = re.compile(r'Super(wo)+man')
>>> mo1 = testRegex.search('The world of Superman')
>>> print mo1
None
>>> mo2 = testRegex.search('The world of Superwoman')
>>> mo2.group()
'Superwoman'
>>> mo3 = testRegex.search('The world of Superwowowoman')
>>> mo3.group()
'Superwowowoman'
중괄호를 이용하여 특정 횟수 반복 패턴 검색
(A){3} # A가 정확하게 3회 반복
(A)(A)(A)
(A){3,5} # A가 3회 ~ 5회 반복
((A)(A)(A)|(A)(A)(A)(A)|(A)(A)(A)(A)(A))
>>> aRegex = re.compile(r'(A){3}')
>>> mo1 = aRegex.search('AAA')
>>> mo1.group()
'AAA'
최대 일치와 최소 일치
(A){3,5} 정규식은 'AAAAA' 문자열에서 'AAA', 'AAAA', 'AAAAA' 와 일치할 수 있다. 최대 일치는 'AAAAA', 최소 일치는 'AAA" 인데, 파이썬의 정규표현식은 기본적으로 최대 일치되는 값을 돌려줍니다. 최소 일치되는 값을 돌려받고 싶다면, 중괄호 뒤에 '?' 기호를 적어주면 됩니다.
>>> aRegex = re.compile(r'(A){3,5}')
>>> mo1 = aRegex.search('AAAAA')
>>> mo1.group()
'AAAAA'
>>> aRegex = re.compile(r'(A){3,5}?')
>>> mo2 = aRegex.search('AAAAA')
>>> mo2.group()
'AAA'
전체 패턴 검색
findall() 매써드 사용
>>> phoneNumRegex = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)')
>>> phoneNumRegex.findall('Cell: 212-555-1234 Work: 212-555-5678')
[('212', '555-1234'), ('212', '555-5678')]
문자 클래스
짧은 문자 |
클래스 의미 |
\d |
0에서 9까지의 임의의 숫자 - (0|1|2|3|4|5|6|7|8|9) 혹은 [0-9] |
\D |
0에서 9까지의 숫자를 제외한 문자열 |
\w |
문자, 숫자 혹은 '_' (word) |
\W |
문자, 숫자 혹은 '_' 가 아닌 모든 글자 |
\s |
빈칸, 탭 또는 줄바꿈 문자 (white space) |
\S |
빈칸, 탭 또는 줄바꿈 문자가 아닌 모든 글자 |
사용자 정의 문자 클래스 만들기
대괄호를 이용하여 사용자 정의 문자 클래스를 정의할 수 있습니다.
예를 들어 대소문자 구분없이 영어의 소문자 하나를 매치시키고 싶다면, 아래와 같이 정의하면 됩니다.
>>> vowelRegex = re.compile(r'[aeiouAEIOU]')
하이픈을 사용하면 범위를 포함시킬 수 있습니다.
>>> alnumRegex = re.compile(r'[a-zA-Z0-9]')
캐럿과 달러 기호 글자
^ - 텍스트의 시작
$ - 텍스트의 끝
>>> beginsWithHello = re.compile(r'^Hello')
와일드카드 문자
정규식에서 '.' 은 와일드카드라고 하며 줄바꿈을 제외한 모든 문자와 일치한다.
>>> atRegex = re.compile(r'.at')
>>> atRegex.findall('The cat in the hat sat on the flat mat.')
['cat', 'hat', 'sat', 'lat', 'mat']
대소문자를 구분하지 않고 일치시키기
>>> regex = re.compile(r'test', re.I)
문자열 매치해서 치환하기
>>> namesRegex = re.compile(r'Agent \w+')
>>> namesRegex.sub('CENSORED', 'Agent Alice gave the secret documents to Agent Bob')
'CENSORED gave the secret documents to CENSORED'
일치하는 텍스트 그 자체를 대체할 텍스트의 일부로 사용해야 하는 경우에는 \1, \2, \3 등과 같이 입력하면 Match 객체의 그룹 1, 2, 3 등으로 대체 됩니다.
>>> namesRegex = re.compile(r'Agent (\w)\w*')
>>> namesRegex.sub(r'\1****', 'Agent Alice gave the secret documents to Agent Bob')
'A**** gave the secret documents to B****'