59doit

[Python] 전처리/정규화 본문

Programming/Python(파이썬)

[Python] 전처리/정규화

yul_S2 2022. 11. 3. 13:30
반응형
  • findall

모듈추가

import re

from re import findall

 

  • 숫자찾기 & 문자열 찾기
from re import findall   # 모듈추가

st1 = '123456 abc훈민정음 ABC_555_6 세종대왕'

# 숫자 찾기
print(findall('1234',st1))       # <출력> ['1234']
print(findall('[0-9]',st1))      # <출력> ['1', '2', '3', '4', '5', '6', '5', '5', '5', '6']
print(findall('[0-9]{3}',st1))   # <출력> ['123', '456', '555']
print(findall('[0-9]{3,}',st1)   # <출력> ['123456', '555']
print(findall('\\d{3,}',st1))    # <출력> ['123456', '555']

# 문자열 찾기
print(findall('[가-힣]{2,}',st1))    # <출력> ['훈민정음', '세종대왕']
print(findall('[a-b]{2,}',st1))     # <출력> ['ab']
print(findall('[a-z|A-Z]{3}',st1))  # <출력> ['abc', 'ABC']

 

  • 특정위치 문자열

접두어/접미어

종료문자

시작문자

st2 = 'test12abcABC 123mbc 456test'

#접두어/접미어
print(findall('^test',st2))       # <출력> ['test']
print(findall('st$',st2))         # <출력> ['st']

#종료문자
print(findall('.bc',st2))         # <출력> ['abc', 'mbc']

#시작문자
print(findall('t.',st2))          # <출력> ['te', 't1', 'te']

 

 

 

  • 단어찾기
from re import findall            # 모듈추가
st3 = 'test^훈민정음 abc 세종*대왕 123$sbc'

words = findall('\\w{3,}',st3)  
print(words)                      
# <출력> ['test', '훈민정음', 'abc', '123', 'sbc']

findall ('[^t]',st3)
# <출력> ['e', 's', '^', '훈', '민', '정', '음', ' ', 'a', 'b', 'c', ' ', '세', '종', '*', '대', '왕', ' ', '1', '2', '3', '$', 's', 'b', 'c']

findall ('[^t]+',st3)            
# <출력> ['es', '^훈민정음 abc 세종*대왕 123$sbc']

 

  • 문자열제외
from re import findall            # 모듈추가
st3 = 'test^훈민정음 abc 세종*대왕 123$sbc'
print(findall('[^^*$]+',st3))   
# <출력> ['test', '훈민정음 abc 세종', '대왕 123', 'sbc']

 

  • 문자열 검사 = match
  • match 메서드는 문자열의 처음부터 정규식과 매치되는지 조사
import re
p=re.compile('[a-z]+')

m= p.match("python")
print(m)
# <출력> <re.Match object; span=(0, 6), match='python'>

"python" 문자열은 [a-z]+ 정규식에 부합되므로 match 객체를 돌려준다.

 

 

 

import re
p=re.compile('[a-z]+')
m= p.match("3 python")
print(m)
# <출력> None

 처음에 나오는 문자 3이 정규식 [a-z]+에 부합되지 않으므로 None을 돌려준다

 

 

패턴 불일치

 

from re import match               # 모듈추가

juminnum = '123567-4890123'
result = match('[0-9]{6}-[1-4][2-5][0-9]{6}',juminnum)
print(result)       #None

if result :
    print("주민번호 일치")
else :
    print("주민번호 확인요함")

 

 

 

 

  • 문자열 치환 = sub

특수문자제거 & 숫자제거

from re import sub

st3 = 'test^훈민정음 abc 세종*대왕 123$sbc'

# 특수문자제거
text1=sub('[\^*$]+','',st3)
print(text1)
# <출력> test훈민정음 abc 세종대왕 123sbc

# 숫자제거
text2 = sub('[0-9]','',st3)
print(text2)
# <출력> test^훈민정음 abc 세종*대왕 $sbc

 

p = re.compile('(blue|white|red)')
r=p.sub('colour', 'blue socks and red shoes')
print(r)

# <출력> colour socks and colour shoes

 

 

p = re.compile('(blue|white|red)')
y=p.sub('colour', 'blue socks and red shoes', count=1)
print(y)

# <출력>  colour socks and red shoes

바꾸기 횟수를 제어하려면 세 번째 매개변수로 count 값을 넘기면 된다.

 

 

 

 

매서드 매개변수

p = re.compile(r"(?P<name>\w+)\s+(?P<phone>(\d+)[-]\d+[-]\d+)")
print(p.sub("\g<phone> \g<name>", "park 010-1234-1234"))    

# <출력> 010-1234-1234 park

이름 + 전화번호의 문자열을 전화번호 + 이름으로 바꾸는 예
sub의 바꿀 문자열 부분에 \g<그룹이름>을 사용하면 정규식의 그룹 이름을 참조

 

 

sub 메서드의 매개변수로 함수 넣기

def hexrepl(match):              # 16진수로 변환하여 돌려주는 함수
    value = int(match.group())
    return hex(value)            #정규식과 매치된 match 객체가 입력

p = re.compile(r'\d+')
z=p.sub(hexrepl, 'Call 65490 for printing, 49152 for user code.')
print(z)        
# <출력> Call 0xffd2 for printing, 0xc000 for user code.

 

 

 

  • split _compile
from re import split,match,compile

 

텍스트자료

multi_line = """http://www.naver.com     
http://www.daum.net
www.hong.com."""

web_site = split("\n",multi_line)
print(web_site)
# <출력> ['http://www.naver.com     ', 'http://www.daum.net', 'www.hong.com.']

 

패턴객체

pattern  = compile("http://")

sel_site = [site for site in web_site if match(pattern,site)]
print(sel_site)
# <출력> ['http://www.naver.com     ', 'http://www.daum.net']

 

 

 

 

 

자연어처리 = preprocessing

 

from re import findall,sub    # 모듈추가
texts = ['대한민국, 우리나라%$만세','안약 50MG 사용!','코리아사람','택시비 5000원']

 

  • 소문자변경
texts_rel = [t.lower()for t in texts]
print("texts_rel:",texts_rel)

# <출력> texts_rel: ['대한민국, 우리나라%$만세', '안약 50mg 사용', '코리아사람', '택시비 5000원']

 

 

  • 숫자제거
texts_re2 = [sub("[0-9]",'',text) for text in texts_rel]
print('texts_re2 :',texts_re2)

# <출력> texts_re2 : ['대한민국, 우리나라%$만세', '안약 mg 사용', '코리아사람', '택시비 원']

 

  • 문자부호제거
texts_re3 = [sub('[,.?!:;]','',text)for text in texts_re2]
print('texts_re3 :',texts_re3)

# <출력> texts_re3 : ['대한민국 우리나라%$만세', '안약 mg 사용', '코리아사람', '택시비 원']

 

 

  • 특수문자제거
str = '[@#$%^&*()]'
texts_re4 = [sub(str,'',text) for text in texts_re3]
print('texts_re4 :',texts_re4)

# <출력> texts_re4 : ['대한민국 우리나라만세', '안약 mg 사용', '코리아사람', '택시비 원']

 

  • 영어제거
texts_re5 = [''.join(findall("[^a-z]",text))for text in texts_re4]
print('texts_re5 :',texts_re5)

# <출력> texts_re5 : ['대한민국 우리나라만세', '안약  사용', '코리아사람', '택시비 원']

 

  • 공백제거
texts_re6 = [' '.join(text.split())for text in texts_re5]
print('texts_re6 :',texts_re6)

# <출력> texts_re6 : ['대한민국 우리나라만세', '안약 사용', '코리아사람', '택시비 원']

 

 

 

전처리 함수 = func

from re import findall,sub
texts = ['대한민국, 우리나라%$만세','안약 50MG 사용!','코리아사람','택시비 5000원']
def clean_text(text) :
    texts_re =text.lower()
    texts_re2=sub('[0-9]','',texts_re)
    texts_re3=sub('[,.?!;:]','',texts_re2)
    texts_re4=sub('[@#$%^&*()]','',texts_re3)
    texts_re5=sub('[a-z]','',texts_re4)
    texts_re6=' '.join(texts_re5.split())
    return texts_re6
texts_result = [clean_text(text) for text in texts]
print(texts_result)

# <출력> ['대한민국 우리나라만세', '안약 사용', '코리아사람', '택시비 원']

 

 

 

 


EX)

주민등록번호를 포함하고 있는 텍스트에 포함된 모든 주민등록번호의 뒷자리를 * 문자로 변경하기

import re

data = """
park 800905-1049118
kim 700905-1059119
"""

pat=re.compile("(\d{6})[-]\d{7}")
print(pat.sub("\g<1>-*******",data))
# <출력>
# park 800905-*******
# kim 700905-*******
  • dot(.) = \n을 제외한 모든 문자와 매치됨
  • a[.]b "a.b" 매치되고 "a0b"와는 매치 안됨
  • ca{2,5}t = >"c+a(2~5회 반복)+t"
  • ab?c = > a+b(있어도 되고 없어도 됨)+c

 

메타문자

  • | : or과 동일한 의미로 사용
p = re.compile('Crow|Servo')
m = p.match('CrowHello')
print(m)

# <출력> <re.Match object; span=(0, 4), match='Crow'>

 

 

  • ^. :문자열의 맨 처음과 일치함
print(re.search('^Life', 'Life is too short'))
# <출력> <re.Match object; span=(0, 4), match='Life'>

print(re.search('^Life', 'My Life'))
# <출력> None

 

 

  • $ : 문자열의 끝과 매치함
print(re.search('short$', 'Life is too short'))
# <출력> <re.Match object; span=(12, 17), match='short'>

print(re.search('short$', 'Life is too short, you need python'))
# <출력> None

 

 

 

  • \A : 문자열의 처음과 매치된다

 

 

 

  • \Z : 문자열의 끝과 매치된다

 

 

  • \b : 단어 구분자
p = re.compile(r'\bclass\b')
print(p.search('no class at all'))
# <출력> <re.Match object; span=(3, 8), match='class'>

 

  • \B : 단어가 아닌경우에만 매치
p = re.compile(r'\Bclass\B')
print(p.search('no class at all'))  
# <출력> None

print(p.search('the declassified algorithm'))
# <출력><re.Match object; span=(6, 11), match='class'>

print(p.search('one subclass is'))
# <출력> None

 

 

 

그루핑

  • 그룹을 만들어 주는 메타 문자 ( )
p = re.compile('(ABC)+')
m = p.search('ABCABCABC OK?')

print(m)
# <출력> <re.Match object; span=(0, 9), match='ABCABCABC'>
print(m.group())  
# <출력> ABCABCABC

 

EX1)

p = re.compile(r"(\w)+\s+\d+[-]\d+[-]\d+")
m = p.search("park 010-1234-1234")
print(m.group(1))

# <출력> park
  • \w+\s+\d+[-]\d+[-]\d+은 이름 + " " + 전화번호 형태의 문자열을 찾는 정규식이다. 
  • 이름에 해당하는 \w+ 부분을 그룹 (\w+)으로 만들면 match 객체의 group(인덱스) 메서드를 사용하여 그루핑된 부분의 문자열만 뽑아낼 수 있다

 

.

EX2)

p = re.compile(r"(\w+)\s+(\d+[-]\d+[-]\d+)")
m = p.search("park 010-1234-1234")
print(m.group(2))

# <출력> 010-1234-1234
  • 전화번호 부분을 추가로 그룹 (\d+[-]\d+[-]\d+)로 만들었다

 

 

 

EX3)

p = re.compile(r"(\w+)\s+((\d+)[-]\d+[-]\d+)")
m = p.search("park 010-1234-1234")
print(m.group(3))

# <출력> 010
  • (\w+)\s+((\d+)[-]\d+[-]\d+)처럼 그룹을 중첩되게 사용하는 것도 가능하다. 
  • 그룹이 중첩되어 있는 경우는 바깥쪽부터 시작하여 안쪽으로 들어갈수록 인덱스가 증가한다.

 

 

 

 

반응형

'Programming > Python(파이썬)' 카테고리의 다른 글

[Python] os 모듈 파일 디렉터리 관련함수  (0) 2022.11.04
[Python] 예외처리  (0) 2022.11.04
[Python] import class (내장클래스)  (0) 2022.11.03
[Python] class  (0) 2022.11.02
[Python] 재귀함수  (0) 2022.11.02
Comments