정규표현식 (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))
'AI > 데이터분석' 카테고리의 다른 글
[Crawling] BeautifulSoup & 정규표현식으로 tag 찾기 (0) | 2020.01.13 |
---|---|
[Crawling] BeautifulSoup 모듈 (2) (0) | 2020.01.13 |
[Crawling] BeautifulSoup 모듈 (0) | 2020.01.13 |
[Crawling] Open API 활용 & json 데이터 추출 (0) | 2020.01.13 |
[Crawling] requests 모듈 사용하기 (0) | 2020.01.13 |