맨땅에 헤딩하는 사람

[Python] re 모듈 사용법 (정규표현식), raw 문자열 본문

파이썬/이론

[Python] re 모듈 사용법 (정규표현식), raw 문자열

purplechip 2020. 5. 1. 21:48

문자열 검색, 치환 등의 기능이 필요할 때 파이썬 내에서 str 클래스의 함수(find, replace)를 사용할 수 있다.

그러나 위 함수는 문자열의 범위에 따른 검색이나 치환의 기능을 수행하는 것, 즉 문자열 패턴에 대해서는 적용이 불가능하다.

 

이를 해결하기 위한 모듈이 바로 re(regular expression)이며

이 글에서는 re 모듈의 기본적인 사용법을 정리한다.

 

문자열 패턴 (메타문자)

  • ^문자열 : 해당 문자열로 시작하는지 확인
  • 문자열$ : 해당 문자열로 끝나는지 확인
  • 문자열|문자열|... : 문자열이 or로 묶였다 생각하면 됌 (들어간 문자열 중 하나라도 있으면 검출)
  • [문자-문자] : [0-9], [0-9a-z] 등으로 사용하며 해당 문자의 범위안에 들어있는 모든 문자 확인 ( [0-9]면, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 중 하나의 문자를 나타냄 )
  • + : 문자 뒤에 사용하며, 해당 문자가 1개 이상인 경우
  • : 문자 뒤에 사용하며, 해당 문자가 0개 이상인 경우
  • ? : 문자 뒤에 사용하며, 해당 문자가 0개 혹은 1개인 경우 
  • . : 문자 뒤에 사용하며, 해당 문자가 1개인 경우
  • {개수} or {처음개수, 끝개수} : 문자 뒤에 사용하며, 해당 문자가 개수, 혹은 처음개수와 끝개수 사이의 개수인 경우
  • [^문자-문자] : ^가 들어가면 해당 문자범위가 아닌 문자를 나타냄 ( [^0-9]면, 0-9 외의 모든 문자 (a-z, A-Z, 가-힣, %,!,@,$,#,! 등등등) )
  • \d : [0-9]와 같음
  • \D : [^0-9]와 같음
  • \w : [a-zA-Z0-9_]와 같음
  • \W : [^a-zA-Z0-9_]와 같음
  • \*, \+, \?, \., \^, \$, \(, \), \[, \], 등 - 각 특수문자 그 자체를 표현하기 위해 사용 
  • \s - [ \t\n\r\f\v]와 같음, 여러가지 줄 관련 기호 (공백, 라인피드, 탭 등등)
  • \S - [^ \t\n\r\f\v]와 같음
  • [가-힣] - 모든 한글 문자 (낱자는 따로 [ㄱ-ㅎㅏ-ㅣ] 명시를 해주어야 됌)

 

패턴 팁

  • 해당범위에서 일정 범위만 제외하고 싶은 경우 [a-z^h] 처럼 동시 사용이 불가능하다. [a-z]가 됌
  • [a-z][0-9]*$라 하면 $가 0-9로 끝나는 경우와 0-9로 안끝나면 a-z로 끝나는 경우의 패턴을 의미한다. 따라서 해당 패턴의 [0-9]가 없을 경우 $는 [a-z]에 적용된다. 아래는 예시

re.match('[a-z][0-9]*$', 'a1111') 
Out[28]: <re.Match object; span=(0, 5), match='a1111'> 

re.match('[a-z][0-9]*$', 'ab')  # match 안됌

re.match('[a-z][0-9]*$', 'a1a') # match 안됌


re.match('[a-z][0-9]*$', 'a') 
Out[30]: <re.Match object; span=(0, 1), match='a'>

 

raw 문자열

문자열에서 특수문자를 나타내기 위해서 \를 앞에 붙여 표현한다. 

그러나 raw 문자열은 특수문자의 의미가 아닌 특수문자 자체를 표현한다. r' '의 형식으로 표현한다.

print('\n')
Out : 


print(r'\n')
Out : \n

print('\\')
Out : \

print(r'\\')
Out : \\

위 예를 통해 확인이 가능하다.

 

 

함수

parameter에서 pattern은 내가 검색이나 치환의 키가 되는 문자열을 의미하고 str은 검색이나 치환의 대상이 되는 문자열이다.

주로 사용하는 함수에 대해 정리하였다.

 

re.compile(pattern, str)

  • pattern 문자열을 정규표현식 객체로 바꿔주는 함수
  • 같은 pattern을 단일 프로그램에서 지속적으로 사용할 때 효율적으로 사용이 가능하다.
  •  re.compile(pattern).match(str)  re.match(pattern, str) 은 동일한 기능

re.match(pattern, str)

  • str의 시작부분이 pattern과 일치하여 일치하는 부분까지 정규표현식 객체로 반환
  • search 함수와 다른 점은 match의 경우 str의 시작부분만 검색

re.search(pattern, str)

  • str 내 pattern과 일치하는 부분을 정규표현식 객체로 반환
  • match 함수와 다른 점은 search의 경우 str 전부를 검색

group(num)

  • 정규표현식 객체를 문자열로 반환하는 함수
  • pattern 구성 시 ()을 사용해서 group을 지정할 수 있으며 group 순서에 따라 num이 1부터 순서대로 할당됌
  • num = 0 인 경우 group 전체의 문자열이 반환
  •  a = re.match(pattern, str); a.group()  와 같은 식으로 사용

re.sub(pattern, 바꿀 str, 기존 str)

  • 기존 str에서 pattern을 찾아 바꿀 str으로 교체하는 함수
  • pattern에서 group을 지정했다면 바꿀 str에서 <\\num>을 사용하여 해당 group의 str을 그대로 사용 가능

 

다음 코드는 compile 함수의 효율성을 보기위해 동작시간을 확인해본 것이다.

import re
import time

time_1 = time.time()

pat = re.compile('[a-z][0-9]*$')
for i in range(1000000): #1,000,000
    pat.search('a100000')
    
time_2 = time.time()

for i in range(1000000): #1,000,000
    re.search('[a-z][0-9]*$', 'a100000')
    
time_3 = time.time()

print('using compile :', time_2 - time_1)
print('not using compile : ', time_3 - time_2)

 출력은 다음과 같다.

using compile : 0.3390934467315674
not using compile :  0.7928822040557861

약 2배 정도 compile을 사용한 경우가 빠르다.

 

 

 

참고

re 함수

https://docs.python.org/3/library/re.html#module-contents

 

메타문자

https://dojang.io/mod/page/view.php?id=2435

 

Comments