NLP(자연어처리) - 정규표현식 with python (1) 글에 이어서 진행됩니다.
메타문자 별도 표기법(자주 사용하는)
앞 글에서 [0-9], [가-힣]과 같은 표현을 보았는데, 이 표현보다는 w와 d처럼 한 문자로 메타문자를 표현하는 방법을 자주 사용한다. 이 글에서는 대표적으로 \w와 \d에 대해 알아보고, 대문자와 소문자의 차이에 대해 다루고자 한다.
text = "텍스트마이닝은 정말 신기해요.ㅎ헤ㅏ핳"
re.findall('[\w]', text)
>>> ['텍','스','트','마','이','닝','은','정','말','신','기','해','요','ㅎ','헤','ㅏ','핳']
re.findall('[\W]', text)
>>> [' ', ' ', '.']
ph = '''안녕하세요. 제 전화번호는 010-1234-5678입니다.'''
re.findall('[\d]', ph)
>>> ['0','1','2','3','4','5','6','7','8']
re.findall('[\D]', ph)
>>> ['안','녕','하','세','요','.',' ','제',' ','전','화','번','호','는',' ','-','-','-','입','니','다','.']
\w : 문자와 숫자 중에 매치 되는 것을 출력해준다. [a-zA-Z0-9]와 같은 의미이다.
\W : 문자와 숫자를 제외한 글자들을 출력해준다. [^a-zA-Z0-9]와 같은 의미이고, 위에서는 공백만을 출력해준다.
\d : 숫자 중에 매치 되는 것을 출력해준다. [0-9]와 같은 의미이다.
\D : 숫자를 제외한 글자들을 출력해준다. [^0-9]와 같은 의미이고, 위에서는 문자와 공백, 특수문자들을 출력해준다.
정리하자면 소문자는 해당 글자를 출력해주고, 대문자는 해당 문자를 제외한 글자들을 출력해준다.
Dot(.) 활용
이제 .이라는 개념이 나오는데, 이 .은 Dot이라고 읽고 뒤의 한 글자와 같이 매치된다. 코드를 살펴보자.
name = '홍길동'
re.findall('홍.', name)
>>> ['홍길']
name2 = '''고길동입니다. 고기먹고 싶어요'''
re.findall('고.', name2)
>>> ['고길', '고기']
위의 출력처럼 name에서 홍.을 했을 때 '홍길'을 출력하고, name2에서 고.을 했을 때 '고길', '고기'를 출력한 것을 볼 수 있다. 즉 .은 뒤에 나오는 글자 하나와 같이 매치되고, 여러 개가 속해 있으면 여러 문자를 반환하는 것을 볼 수 있다.
반복(*, +, { }, ?) 활용
문자들을 찾는 것 외에도, 해당 문자를 원하는 만큼 반복할 수 있다. 반복 기호는 주로 *, + { }, ?를 쓰며 각자의 용도는 코드를 통해 알아보자.
name = "홍동 홍길동 홍길길동 홍길길길동"
re.findall('홍길*동', name)
>>> ['홍동','홍길동','홍길길동','홍길길길동']
re.findall('홍길+동', name)
>>> ['홍길동','홍길길동','홍길길길동']
re.findall('홍길{3}동', name)
>>> ['홍길길길동']
re.findall('홍길{1,2}동', name)
>>> ['홍길동', '홍길길동']
re.findall('홍길?동', name)
>>> ['홍동','홍길동']
* : 0번 반복하는 것부터 무한히 반복하는 것까지 출력해준다. 그래서 홍동과 홍길길길동까지 모든 문자들이 출력되었다.
+ : 적어도 1번이상 반복하는 것들을 출력해준다. 홍동은 길이 0번 반복되기 때문에 출력되지 않았다.
{ } : 정해준 범위 만큼 반복하는 것을 출력한다. {3}이라고 적었으므로, 길이 3번 반복되는 홍길길길동이 출력되었다. { } 안에는 범위를 지정할 수도 있는데, {1,2}라고 적는다면 1이상 2이하만큼 반복되는 것을 출력한다.
? : 0번 혹은 1번 반복하는 것을 출력한다.
그루핑
문자열 중에서 원하는 문자만 그룹화하여 추출할 수 있다. 그룹은 ( )를 활용하여 묶어줄 수 있고, ?P<>를 활용하면 그룹의 이름을 지정해줄 수 있다.
info = '''
홍길동 010-1234-5678
고길동 010-2345-6789
박길동 010-3456-7890
'''
group = re.search(r"(\w+)\s+(\d+)-?(\d+)-?(\d+)", info)
group.group(0)
>>> '홍길동 010-1234-5678'
group2 = re.search(r"(?P<name>\w+)\s+(\d+)-?(\d+)-?(\d+)", info)
group2.group("name")
>>> '홍길동'
group3 = re.findall(r'(\w+)\s+\d{3}-\d{4}-(\d{4})', info)
group3
>>> [('홍길동', '5678'), ('고길동', '6789'), ('박길동', '7890')]
이름과 전화번호가 매치된 info가 있다고 가정했을 때, 기존 사용했던 메타문자들을 조합해 그룹화할 수 있다. 여기서 r은 string으로 가져오라는 뜻이다.
그룹화했을 때, (0), (1)과 같이 group에서 원하는 정보만을 뽑을 수 있다.
또한 ?P< >를 통해 그룹의 이름을 지정해줘서, group("name")과 같이 이름을 반환해주면 '홍길동'이라는 값이 매치되므로 출력된다.
마지막으로 메타문자에서 원하는 부분만 추출하기 위해서 ( )를 활용할 수 있다. 위 코드에서는 첫번째 문자와 4번째 문자만을 가져와서 이름과 전화번호 뒷자리 4자리만이 출력됐다.
sub 메서드
마지막으로 sub메서드라는 기능을 통해, 문자열을 원하는 문자로 대체할 수 있다.
표현은 re.sub(대체하고 싶은 문자, 대체할 문자, 텍스트)이다. 여기서 주의할 점은 대체하고 싶은 문자에서 패턴이 있다면 해당 패턴을 메타문자를 통해 나타내줘야 한다.
text = "연어초밥 너무 먹고 싶어요 하ㅏㅠ휴"
re.sub("너무","너무너무",text)
>>> '연어초밥 너무너무 먹고 싶어요 하ㅏㅠ휴'
re.sub("[ㄱ-ㅣ]", "", text)
>>> '연어초밥 너무 먹고 싶어요 하휴'
해당 텍스트에서 너무라는 단어를 너무너무로 바꾸고 싶다면 sub메서드를 사용하면 되고, 뒤에 ㅏㅠ라는 글자들을 지우고 싶다면 [ ]안에 문자를 넣어 공백으로 대체해줄 수 있다.
'딥러닝 > 자연어처리' 카테고리의 다른 글
NLP논문리뷰 - ELMo (Deep contextualized word representations) (0) | 2021.03.31 |
---|---|
NLP - FastText 논문리뷰 (Enriching Word Vectors with Subword Information) (0) | 2021.03.18 |
[파이썬으로 배우는 응용 텍스트 분석] 텍스트 분석 도구 (0) | 2021.02.18 |
NLP(자연어처리) - 정규표현식 with python (1) (0) | 2021.02.10 |
[자연어처리] 공부내용 정리 - 기초 1 (0) | 2020.10.09 |
최근댓글