티스토리 뷰
정규표현식 (re Module)
#. re 모듈
import re
- 정규식 처리 모듈
- 패턴 매칭, 치환, 분리
text = 'lololo'
1. findall 메서드
- re.findall(pattern, string, flags=0)
- 패턴과 일치하는 모든 원소 출력 * 주로 사용
- 벡터 연산 불가
re.findall('ol', text)
['ol', 'ol']
2. search 메서드
- re.search(pattern, string, flags=0)
- 패턴과 일치하는 첫 번째 원소 출력
- 직접 출력 불가 => group 메서드 사용
re.search('ol', text)
<re.Match object; span=(1, 3), match='ol'>
re.search('ol' , text).group(0)
'ol'
3. match 메서드
- re.match(pattern, string, flags=0)
- 시작 부분에서 패턴과 일치하는 원소만 출력
re.match('ol' , text)
# text가 특정 패턴으로 시작하지 않으므로 공백 출력
re.match('lo' , text).group(0)
'ol'
#. Pattern
[] |
하나의 패턴 |
{n,m} |
n회 이상 m회 이하 |
* | 0회 이상 반복 |
+ | 1회 이상 반복 |
? | 0회 이상 1회 이하 |
. |
\n(개행문자)를 제외한 모든 문자와 매치 (점 개수 = 글자 개수) |
| |
or |
^ |
문자열의 시작 |
$ |
문자열의 끝 |
\ |
메타 문자(. , : ..)를 일반 문자로 변환 |
() |
추출할 패턴 그루핑 |
#. Ex
# 이메일 주소를 검사하는 정규 표현식
text = """bingo@google.com # 개행문자를 포함하는 문자열
hello@gmail.com
olleh@gmail.com
niceto@yahoo.com
notme"""
'bingo@google.com\nhello@gmail.com\nolleh@gmail.com\nniceto@yahoo.com\nnotme'
# 1. 패턴 저장
pattern = r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'
regex = re.compile(pattern , flags = re.IGNORECASE)
# 자주 사용되는 정규표현식을 재사용할 수 있도록 저장 (효율적인 cpu 사용)
# flags = re.IGNORECASE : 정규표현식이 대소문자를 가리지 않게 설정
# 2. 패턴과 일치하는 모든 이메일 출력
regex.findall(text)
['bingo@google.com', 'hello@gmail.com', 'olleh@gmail.com', 'niceto@yahoo.com']
regex.search(text) # 패턴과 일치하는 첫 번째 원소 출력
<re.Match object; span=(0, 16), match='bingo@google.com'>
regex.search(text).group(0)
# 3. group메서드의 사용
- group(0) : 패턴과 일치하는 전체 그룹 추출
- group(1) : 패턴과 일치하는 첫 번째 그룹 추출
- group(2) : 패턴과 일치하는 두 번째 그룹 추출
- group(...) : ...
regex2 = re.compile('([a-z]+)@([a-z]+)\.[a-z][a-z][a-z]') # () : 추출할 패턴 grouping
regex2.findall(text)
[('bingo', 'google'),
('hello', 'gmail'),
('olleh', 'gmail'),
('niceto', 'yahoo')]
regex2.search(text).group(0)
'bingo@google.com'
regex2.search(text).group(1)
'bingo'
regex2.search(text).group(2)
'google'
#. 벡터화 문자열 추출 (str())
- findall 메서드를 Series, DataFrame에도 적용하기 위한 함수
- 벡터 연산이 가능한 findall 메서드
- 그룹을 가지면 리스트 형식으로 저장
- str.get() 또는 str 속성 색인으로 벡터화된 요소 추출 가능
df1 = DataFrame(['adf aaa@naver.com dsdsdsds1252525' , 'dw34 bbbb@daum.net erewe' , '340 df23 cc@hanmail.net'] , columns = ['col1'])
pattern1 = re.compile('[a-z]+@[a-z]+\.[a-z]+') # 그룹화 X
pattern2 = re.compile('([a-z]+)@[a-z]+\.[a-z]+') # 이메일 아이디만 그룹화
pattern3 = re.compile('([a-z]+)@([a-z]+)\.([a-z]+)') # 전부 그룹화
# 그룹화가 없는 패턴
df1['col1'].str.findall(pattern1)
0 [aaa@naver.com]
1 [bbbb@daum.net]
2 [cc@hanmail.net]
Name: col1, dtype: object
df1['col1'].str.findall(pattern1).str[0]
df1['col1'].str.findall(pattern1).str.get(0)
0 aaa@naver.com
1 bbbb@daum.net
2 cc@hanmail.net
Name: col1, dtype: object
# 이메일 아이디만 그룹화
df1['col1'].str.findall(pattern2)
0 [aaa]
1 [bbbb]
2 [cc]
Name: col1, dtype: object
df1['col1'].str.findall(pattern2).str[0]
df1['col1'].str.findall(pattern2).str.get(0)
0 aaa
1 bbbb
2 cc
Name: col1, dtype: object
# 이메일 전부 그룹화
df1['col1'].str.findall(pattern3).str.get(0)
0 (aaa, naver, com)
1 (bbbb, daum, net)
2 (cc, hanmail, net)
Name: col1, dtype: object
df1['col1'].str.findall(pattern3).str.get(0).str[0]
0 aaa
1 bbbb
2 cc
Name: col1, dtype: object
df1['col1'].str.findall(pattern3).str.get(0).str[1]
0 naver
1 daum
2 hanmail
Name: col1, dtype: object
df1['col1'].str.findall(pattern3).str.get(0).str[2]
0 com
1 net
2 net
Name: col1, dtype: object
# 문자열의 포함 여부 확인 (.str.contains)
df1['col1'].str.findall(pattern1).str[0].str.contains('naver')
0 True
1 False
2 False
Name: col1, dtype: bool
#. Q1
a = !type shoppingmall.txt # 쇼핑몰 검색 크롤링 데이터
type(a)
IPython.utils.text.SList
a = str(a)
type(a)
str
site_pattern = re.compile('[a-z]+://[a-z0-9.-_]+', flags = re.IGNORECASE)
result = site_pattern.findall(a)
result
#. Q2
### ncs학원검색.txt 파일을 읽고 데이터 프레임 작성
data = open('ncs학원검색.txt' , 'r')
data = data.readlines()
# 정규표현식 작성
# .(온점)은 엔터를 포함한 모든 문자열을 의미
# 아이티윌 ( 서울 강남구 ☎ 02-6255-8002 ) 훈련기관정보보기 훈련기간 : 2018-10-12 ~ 2019-03-27
pattern1 = re.compile('(.+) \((.+) \u260E (.+) \) .+ : (.+) ~ (.+)')
df1 = DataFrame(data, columns=['text']) # DataFrame 형태로 변환
result = df1['text'].str.findall(pattern1).str.get(0).dropna() # findall 메서드로 정규표현식을 적용하고 NA 제거
# 그룹별 컬럼으로 분할
col1 = result.str.get(0).str.strip() # str.strip 은 벡터연산 가능
col2 = result.str.get(1).str.strip()
col3 = result.str.get(2).str.strip()
col4 = result.str.get(3).str.strip()
col5 = result.str.get(4).str.strip()
academy = DataFrame({'name':col1, 'addr':col2, 'tel':col3, 'start':col4, 'end':col5})
academy.iloc[:5]
#. Q3
### oracle_alert_testdb.log 파일을 읽고
data = open('oracle_alert_testdb.log', 'r')
data = data.readlines()
df1 = DataFrame(data, columns=['error'])
# ORA 코드와 그에 해당하는 오류 메시지 출력
# 정규식은 공백의 포함에 민감한데, 발생 가능한 모든 문자를 포함하는 '.+' 사용하면 편리
pattern = re.compile('(ORA-[0-9]+):(.+)')
result = df1['error'].str.findall(pattern).str.get(0).dropna()
col1 = result.str.get(0).str.strip()
col2 = result.str.get(1).str.strip()
ora = DataFrame({'code':col1, 'msg':col2})
ora
참고: KIC 캠퍼스 머신러닝기반의 빅데이터분석 양성과정
'Python > Process' 카테고리의 다른 글
[Python] 시계열 데이터 가공 (0) | 2019.02.20 |
---|---|
[Python] 그룹 연산 (Group by) (8) | 2019.02.19 |
[Python] DataFrame의 데이터 변형 메서드 (0) | 2019.02.15 |
[Python] 피벗 (.pivot, .pivot_table) (0) | 2019.02.14 |
[Python] 데이터 결합 (np.concatenate, pd.concat) (0) | 2019.02.14 |