59doit
[Python] 전처리/정규화 본문
반응형
- 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