티스토리 뷰

시작에 앞서 본 내용은 새롭게 알게 된 정보 또는 방법론을 기록하기 위함이며 내용에 부족한 점이 있으니 이점 유의 부탁드립니다.

띄어쓰기 없이
여러 번 반복되는 문자 처리


바로 알아보기
re.sub(f'(\\S{{{n},}}?)\\1+', '\\1', i)


활용방향
Ex_Before : "Eazyyyyyyyyyyy" ,
                      "아ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 진짜 웃겨ㅕㅕㅕㅕ",
                      "어쩔티비어쩔티비어쩔티비어쩔티비"

Ex_After : "Eazy" ,
                   "아ㅋ 진짜 웃겨ㅕ",
                   "어쩔티비"

텍스트 전처리 과정에서 위 예시와 같이 의미 없는 반복된 문자를 마주하게 되는데,
이 처럼 띄어쓰기 없이 반복되는 문자는 단어 토큰을 증가시키는데 한몫 한다.
여러 번 반복되는 문자를 한 자리만 남도록 하여 단어 토큰 통일화하려는 시도로써,
정규표현식을 통해 해결하고자 한다.

용어 설명
본 내용 이해에 필요한 일부 정규표현식 설명
------------------------------------

1. \\S : 공백 문자를 제외한 모든 문자를 의미한다.

2. 문자패턴n|문자패턴m : 또는(or)을 표현,
                                         문자패턴n 또는 문자패턴m에 해당하는 문자를 의미한다.

3. [문자n-문자m] : 대괄호는 문자의 범위를 표현,
                                문자n과 문자m 사이의 모든 문자를 의미한다.

4. 문자{n} : 중괄호는 반복을 표현,
                    문자가 n번 반복됨을 의미한다.

5-1. (문자) : 소괄호는 그룹을 표현,
                     소괄호 안의 해당 문자 패턴을 그룹화함을 의미한다.

5-2. (문자1)...(문자n) : 하나 이상의 그룹을 표현,
                                        괄호 안의 해당 문자 패턴을 각 그룹화함을 의미한다.

6. \\1, \\n : 순서를 부여받은 그룹을 표현,
                   각 번호에 해당하는 그룹의 문자를 의미한다.

* 각 그룹들은 순서대로 번호를 부여하여 관리된다.
* 본 내용에 작성된 n, m의 의미는 임의의 정수 번호를 의미한다. 

예시 데이터 소개
foo = [
    'ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ',
    '웃겨ㅕㅕㅕㅕㅕㅕㅕㅕㅕㅕ',
    '빼에에에에에에에에에에엑',
    '와아아아아아아아아아아아',
    '응ㅋ어쩔어쩔어쩔어쩔어쩔',
    '어쩔티비어쩔티비어쩔티비',
]

정규표현식
module re in Python
  • 한 자리 문자 처리

    - 반복되는 문자(모음, 자음, 음절 포함)

import re
for i in foo:
    print(i ,'->', re.sub('(\\S)\\1+', '\\1', i))
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ -> ㅋ
웃겨ㅕㅕㅕㅕㅕㅕㅕㅕㅕㅕ -> 웃겨ㅕ
빼에에에에에에에에에에엑 -> 빼에엑
와아아아아아아아아아아아 -> 와아
응ㅋ어쩔어쩔어쩔어쩔어쩔 -> 응ㅋ어쩔어쩔어쩔어쩔어쩔
어쩔티비어쩔티비어쩔티비 -> 어쩔티비어쩔티비어쩔티비

# 정규표현식 설명
re.sub('(\\S)\\1+', '\\1', i)

re.sub('(\\S)\\1+', '\\1', i)
(\\S) : 공백을 포함하지 않는 한 자리 문자를 그룹으로 잡는다.
 \\1+ : 그룹으로 잡힌 문자가 1개 이상 존재하는 패턴을 찾는다.

re.sub('(\\S)\\1+', '\\1', i)
\\1 : 앞서 찾은 패턴을 그룹으로 잡힌 문자로 변경한다.

 

 

    - 반복되는 음절

import re
for i in foo:
    print(re.sub('([가-힣])\\1+', '\\1', i))
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ -> ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
웃겨ㅕㅕㅕㅕㅕㅕㅕㅕㅕㅕ -> 웃겨ㅕㅕㅕㅕㅕㅕㅕㅕㅕㅕ
빼에에에에에에에에에에엑 -> 빼에엑
와아아아아아아아아아아아 -> 와아
응ㅋ어쩔어쩔어쩔어쩔어쩔 -> 응ㅋ어쩔어쩔어쩔어쩔어쩔
어쩔티비어쩔티비어쩔티비 -> 어쩔티비어쩔티비어쩔티비

# 정규표현식 설명 
re.sub('([가-힣])\\1+', '\\1', i)

re.sub('([가-힣])\\1+', '\\1', i)
([가-힣]) : "가"부터 "힣"사이에 존재하는 한 자리 문자만 그룹으로 잡는다.
 \\1+ : 그룹으로 잡힌 문자가 1개 이상 존재하는 패턴을 찾는다.

re.sub('([가-힣])\\1+', '\\1', i)
\\1 : 앞서 찾은 패턴을 그룹으로 잡힌 문자로 변경한다.

* [가-힣]을 사용하여 한글 음절(각 모음, 자음은 제외)만 패턴으로 찾는다.

  • 두 자리 이상 문자 처리

    - 반복되는 2자리 문자 처리

import re
for i in foo:
    print(i ,'->', re.sub('(\\S{2})\\1+', '\\1', i))
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ -> ㅋ
웃겨ㅕㅕㅕㅕㅕㅕㅕㅕㅕㅕ -> 웃겨ㅕ
빼에에에에에에에에에에엑 -> 빼에엑
와아아아아아아아아아아아 -> 와아
응ㅋ어쩔어쩔어쩔어쩔어쩔 -> 응ㅋ어쩔어쩔어쩔어쩔어쩔
어쩔티비어쩔티비어쩔티비 -> 어쩔티비어쩔티비어쩔티비

# 정규표현식 설명
re.sub('(\\S{2})\\1+', '\\1', i)

re.sub('(\\S{2})\\1+', '\\1', i)
(\\S{2}) : 공백을 포함하지 않는 두 자리 문자를 그룹으로 잡는다.
 \\1+ : 그룹으로 잡힌 문자가 1개 이상 존재하는 패턴을 찾는다.

re.sub('(\\S{2})\\1+', '\\1', i)
\\1 : 앞서 찾은 패턴을 그룹으로 잡힌 문자로 변경한다.

 

 

    - 반복되는 n자리 문자 처리

import re
num = 4  # 사용자 입력 : 반복되는 n자리수 최대 값
for i in foo:
    i_ = i
    for n in reversed(range(1, num+1)):
        i_ = re.sub(f'(\\S{{{n}}})\\1+', '\\1', i_)  
    print(i ,'->', i_)
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ -> ㅋ
웃겨ㅕㅕㅕㅕㅕㅕㅕㅕㅕㅕ -> 웃겨ㅕ
빼에에에에에에에에에에엑 -> 빼에엑
와아아아아아아아아아아아 -> 와아
응ㅋ어쩔어쩔어쩔어쩔어쩔 -> 응ㅋ어쩔
어쩔티비어쩔티비어쩔티비 -> 어쩔티비

# 정규표현식 설명
re.sub(f'(\\S{{{n}}})\\1+', '\\1', i)

re.sub(f'(\\S{{{n}}})\\1+', '\\1', i)
re.sub('(\\S{n})\\1+', '\\1', i)  # 위 표현식을 이해하기 쉽게 임의적으로 변경
(\\S{n}) : 공백을 포함하지 않는 n 자리 문자를 그룹으로 잡는다.
 \\1+ : 그룹으로 잡힌 문자가 1개 이상 존재하는 패턴을 찾는다.

re.sub(f'(\\S{{{n}}})\\1+', '\\1', i)
\\1 : 앞서 찾은 패턴을 그룹으로 잡힌 문자로 변경한다.

글을 마무리하며
  • 반복되는 n자리 문자 처리의 경우,
    for loop가 아닌 정규표현식 자체적으로 처리할 방법이 있는지 고민이 필요.

 

    - 해결

import re
n = 1
for i in foo:
    print(i ,'->', re.sub(f'(\\S{{{n},}}?)\\1+', '\\1', i))
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ -> ㅋ
웃겨ㅕㅕㅕㅕㅕㅕㅕㅕㅕㅕ -> 웃겨ㅕ
빼에에에에에에에에에에엑 -> 빼에엑
와아아아아아아아아아아아 -> 와아
응ㅋ어쩔어쩔어쩔어쩔어쩔 -> 응ㅋ어쩔
어쩔티비어쩔티비어쩔티비 -> 어쩔티비

# 정규표현식 설명
re.sub(f'(\\S{{{n},}}?)\\1+', '\\1', i)

re.sub(f'(\\S{{{n},}}?)\\1+', '\\1', i)
re.sub(f'(\\S{n,)?)\\1+', '\\1', i)  # 위 표현식을 이해하기 쉽게 임의적으로 변경
(\\S{n,)?) :공백을 포함하지 않는 n 자리 이상 문자를 그룹으로 잡으며 ?를 통해 Lazy 방식으로  동작하게 된다.
\\+1 :
그룹으로 잡힌 문자가 1개 이상 존재하는 패턴을 찾는다.

re.sub(f'(\\S{{{n},}}?)\\1+', '\\1', i)
\\1 : 앞서 찾은 패턴을 그룹으로 잡힌 문자로 변경한다.

* ?, Lazy와 관련된 내용은 따로 정리하여 올리도록 하겠습니다.
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함