본문으로 바로가기

정규표현식(re)

category AI/데이터분석 2020. 1. 12. 22:06
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

 

 

 

 

정규표현식 (regular expression)

 

정규 표현식(正規表現式, 영어: regular expression, 간단히 regexp[1] 또는 regex, rational expression)[2][3] 또는 정규식(正規式)은 특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식 언어이다. 정규 표현식은 많은 텍스트 편집기 프로그래밍 언어에서 문자열의 검색과 치환을 위해 지원하고 있으며, 특히  Tcl은 언어 자체에 강력한 정규 표현식을 구현하고 있다.

출처 : 위키피디아 (https://ko.wikipedia.org/wiki/%EC%A0%95%EA%B7%9C_%ED%91%9C%ED%98%84%EC%8B%9D)

 

 

- 특정한 패턴과 일치하는 문자열을 검색, 치환, 제거 하는 기능을 지원함.

- 정규표현식 없이 rule 기반으로 패턴을 찾을 수 있으나 이는 불완전하거나 높은 cost가 필요함.

 

 


raw string

문자열 앞에 r을 붙이면 문자열 구성 그대로를 반환하게 됨.

a = 'abcdef\n'
b = r'abcdef\n'

ㅏㅇㄴ머;ㅍ른위의 a와 b를 출력하면 a는 abcdef와 한줄이 바뀐 문자열로 출력되지만

b의 경우는 문자그대로 abcdef\n 이 출력된다.

 


문자 패턴

. : 어떤 하나의 문자와 일치. (개행(엔터)는 포함하지 않음)

\w : 문자 character와 일치 [a-zA-Z0-9_]

\s : 공백문자와 일치

\t, \n, \r : tab, newline, return

\d : 숫자 character와 일치 [0-9]

^ : 문자열의 시작

& : 문자열의 끝

 

\ 문자가 붙으면 해당 문자의 special 한 의미가 사라짐.

예를 들면, . 은 아무 문자 하나였지만

\. 같은 경우에는 정말 점인 . 을 의미하게 된다.

 

 


Search method

첫번째 패턴을 찾으면 match 객체를 반환함.

찾지못하면 None 을 반환함.

 

import re

m = re.search(r'nana', 'banana')
print(m.start())
print(m.end())
print(m.group())

 

m = re.search(r'\d\d\d\w', '119station')
print(m)

 

 


[ ] : 문자 범위

[ ] 안의 문자 중 하나만 만족하면 됨.

 

[abcd] : a or b or c or d

 

[abc.^] : a or b or c or . or ^

이 때 [ ] 대괄호 안의 . 은 special의 의미를 갖지않고 문자그대로 . 을 의미.

 

[0-9] : 모든 숫자

[a-z] : 모든 소문자

 

대괄호 안에서 ^ 가 맨 앞에 사용되면 뒤의 문자들이 아닌 것을 의미함.

[^a-zA-Z] : 알파벳 문자가 아닌 모든 문자.

 

 

m1 = re.search(r'[0-9]wow[0-9]','123wow456')
m2 = re.search(r'[^0-9]wow[0-9]','123wow456')
print(m1)
print(m2)

 

 


반복

* : 0번 이상

+ : 1번 이상

? : 0번 또는 1번

 

반복 패턴의 경우 정규표현식은 greedy하게 문자열을 매칭시킴.

즉, 일치하는 문자열 중 가장 길이가 긴 문자열을 반환함.

 

re.search(r'a[bcd]*d','abbdcdbccd')

위의 예시에서도 일치하는 문자열은 abbd, abbdcd, abbdcdbccd 3가지가 존재하는데

그 중 가장 길이가 긴 마지막 문자열을 반환한다.

 

 


Grouping

( ) 을 사용해서 그룹핑함.

매칭 결과를 원하는 그룹별로 나눌 수 있음.

 

m = re.search(r'(\w+)@(\w+.\w+)', 'test@gmail.com')
print(m.group(0))
print(m.group(1))
print(m.group(2))

group(0) 은 문자열 전체가

그 다음 인덱스부터는 지정한 그룹들이 출력된다.

 

 


{ }

중괄호 같은 경우 횟수를 제한해서 반복을 찾을 수 있다.

a{3} : aaa를 찾아라

a{3,5} : a가 3~5번 있는지 찾아라.

 

 


Non-greedy way

*?, +? 를 이용하면 제일 긴 부분이 아닌 미니멈하게 매칭시켜 줌.

 

{a,b}? : 최소 a 번만 매칭하면 만족함.

 

 


match

search와 비슷하지만 시작부터 비교함.

시작부터 존재하지 않으면 None을 반환.

search에서 문자열 시작에 ^을 붙인것과 동일한 기능.

 

 


findall

search는 최초의 매칭 패턴만 반환하지만

findall은 매칭 되는 모든 패턴을 리스트로 반환함.

 

re.findall(r'\w*pp\w*','apple wow hello pineapple app')

 

 


sub

문자열에서 매칭 패턴을 찾으면 해당 부분을 substitute 즉, 대체함.

문자열을 원하는 문자열로 바꾼다는 것.

sub(패턴, 바꿀 문자열, 찾을 문자열)

 

re.sub(r'\w*pp\w*','cc','apple wow hello pineapple app')

 

 


compile

정규식 표현을 여러번 쓰기위해 re.RegexObject 객체로 저장하여 여러번 사용 가능.

기존사용법에서 패턴을 적어주지 않아도 됨.

 

my_pattern = re.compile(r'\w*pp\w*')
original = 'apple wow hello pineapple app'

print(my_pattern.search(original))
print(my_pattern.findall(original))
print(my_pattern.sub('cc', original))