이 포스팅은 Regular Expression 시리즈 12 편 중 12 번째 글 입니다.

  • Part 1 - 01: 개념잡기
  • Part 2 - 02: 간단한 메타문자
  • Part 3 - 03: re module
  • Part 4 - 04: match 객체의 메서드
  • Part 5 - 05: Compile Option(컴파일 옵션)
  • Part 6 - 06: 파이썬 백슬래시 문제
  • Part 7 - 07: 다양한 메타문자
  • Part 8 - 08: Grouping(그루핑)
  • Part 9 - 09: 전방 탐색(Lookahead Assertions)
  • Part 10 - 10: 문자열 바꾸기
  • Part 11 - 11: Greedy 와 Non-Greedy
  • Part 12 - This Post
▼ 목록 보기

컴파일 버전은 생략하고 실전 지향적으로 간다.

순서

  1. import re
  2. 패턴 입력
  3. 텍스트 준비 (r””) 사용
  4. 검색 (match, search, findall, finditer)
  5. 각각의 메서드에 맞는 메서드 호출

기본 골자

import re #일단 import
pattern = r"ca" # 패턴 입력
text = "bbbbbbcaabsacasca" # 텍스트

검색 메서드

match

문자열의 시작 부분부터 매칭이 되는지 검색

  1. group() : 매칭된 문자열 반환
  2. start() : 시작 위치
  3. end() : 종료 위치
  4. span() : 시작과 종료위치를 튜플로 반환

기본 객체가 MatchOB이다. 그래서 얘도 알고는 있어야 함

문자열에 패턴과 매칭되는 곳이 있는지 검색

match와의 차이점을 알아야 하는데, 시작 부분 아니어도 검색한다. 하지만 검색되면 시작 부분을 반환한다.

text aaa aaaB Baaa BBB
re.match(r’aaa’, text) O O X X
re.search(r’aaa’, text) O O O X
import re #일단 import
pattern = r"ca" # 패턴 입력
text = "bbbbbbcaabsacasca" # 텍스트
matchOB = re.search(pattern, text)
if matchOB:
	print (matchOB)
	print (matchOB.group()) # 매칭된 문자열 # ca
	print (matchOB.start())# 매칭된 문자열 시작 위치 # 0
	print (matchOB.end())   # 매칭된 문자열 종료 위치 # 2
	print (matchOB.span())  # 매칭된 문자열 시작,종료 위치 # (0, 2)

findall

정규식과 매치되는 모든 문자열을 리스트로 반환

pattern = r"ca"
text = "caabsacasca"
# 매칭된 값은 리스트로 모두 반환
matchedList = re.findall(pattern,text)
if matchedList:
	print(matchedList) # ['ca', 'ca', 'ca']

sub

re.sub('\d{4}', 'XXXX', '010-1234-5678') # 010-XXXX-XXXX

정규 표현식에 맞는 표현을 변환할 수 있다. 복잡할수록 좋겠지? 그리고 {}는 범위 혹은 개수를 나타낸다.

text = 'Gorio, Gorio, Gorio keep a straight face.'
re.sub('Gorio', 'Ryan', count=2, text)
# Ryan, Ryan, Gorio keep a straight face.

개수까지 지정할 수 있다.

문자열

사실 sub는 문자열을 제거하는 용도로 많이 사용한다.

pattern = r'[^0-9a-zA-Z]+'
text = """<html lang="ko" xml:lang="ko" xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="utf-8">
  <meta property="og:url" content="https://www.kakaocorp.com"/>
</head>  
<body>
con%    muzI92apeach&2<a href="https://hashcode.co.kr/tos"></a>

    ^
</body>
</html>"""
matchedList = re.findall(pattern, text)
matchedList

이렇게 하면 모든 문자를 찾을 수 있다. 그런데 여기서 이렇게 변경하면,

pattern = r'[^0-9a-zA-Z]+'
text = """<html lang="ko" xml:lang="ko" xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="utf-8">
  <meta property="og:url" content="https://www.kakaocorp.com"/>
</head>  
<body>
con%    muzI92apeach&2<a href="https://hashcode.co.kr/tos"></a>

    ^
</body>
</html>"""
matched = re.sub(pattern, " ", text)
matched
 html lang ko xml lang ko xmlns http www w3 org 1999 xhtml head meta charset utf 8 meta property og url content https www kakaocorp com head body con muzI92apeach 2 a href https hashcode co kr tos a body html 

이와 같이 숫자, 알파벳이 아닌 모든 요소에 대해 값을 제거할 수 있다.

subn

text = 'Gorio, Gorio, Gorio keep a straight face.'
re.subn('Gorio', 'Ryan', count=2, text)
# ('Ryan, Ryan, Gorio keep a straight face.', 2)

값을 튜플로 리턴해준다.

정규 표현식 패턴

표현식 설명  
^ 문자열의 시작  
$ 문자열의 종료  
. 임의의 한 문자  
* 앞문자가 없을 수도 무한정 많을 수도 있음  
+ 앞 문자가 하나 이상  
? 앞 문자가 없거나 하나 있음  
[] 문자의 집합이나 범위를 나타냄, 두 문자사이는 -로 범위를 나타냄  
{} 횟수 또는 범위를 나타냄  
() 소괄호 안의 문자를 하나의 문자로 인식  
<p> </p> 패턴안에서 or 연산을 수행
\s 공백문자  
\S 공백문자가 아닌 나머지 문자  
\w 알파벳이나 숫자  
\W 알파벳이나 숫자를 제외한 문자  
\d 숫자 [0-9]와 동일  
\D 숫자를 제외한 모든 문자  
| 정규표현식 역슬래시는 확장 문자    
(?!) 앞 부분에 (?!)를 넣어 대소문자 구분하지 않음