티스토리 뷰

반응형

정규표현식 (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)

'bingo@google.com'


# 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 캠퍼스 머신러닝기반의 빅데이터분석 양성과정

반응형
댓글
최근에 올라온 글
최근에 달린 댓글
링크
Total
Today
Yesterday