Python, 문자열에서 알파벳이 아닌 모든 문자 제거


90

파이썬 MapReduce 단어 수 프로그램을 작성 중입니다. 문제는 데이터에 흩어져있는 많은 비 알파벳 문자가 있다는 것입니다.이 게시물 은 정규식을 사용하여 멋진 솔루션을 보여주는 Python의 문자열에서 영숫자 문자를 제외한 모든 것을 제거했지만 구현 방법을 모르겠습니다

def mapfn(k, v):
    print v
    import re, string 
    pattern = re.compile('[\W_]+')
    v = pattern.match(v)
    print v
    for w in v.split():
        yield w, 1

나는 re그 문제에 대해 라이브러리 또는 정규식 을 사용하는 방법을 잘 모르겠습니다 . v영숫자가 아닌 문자없이 새 줄을 검색 하기 위해 들어오는 문자열 (책의 줄)에 정규식 패턴을 적용하는 방법을 잘 모르겠습니다 .

제안?


v책의 전체 라인 (특히 moby dick), 나는 char 단위가 아닌 단어 단위로 가고 있습니다. 따라서 일부 단어는 끝에 ","가있을 수 있으므로 "indignity"는 "indignity"와 매핑되지 않습니다.
KDecker 2014 년


Lolx-저와 같은 사전 인터뷰 가정 운동을 받았습니까? Moby Dick에서 가장 많이 사용되는 50 개의 단어를 찾아 그 빈도를보고합니다. 나는 C ++, IIRC에서 그것을했다
Mawg는 Monica

1
@Mawg 학부 "클라우드 컴퓨팅"수업에서 연습 한 것입니다.
KDecker

답변:


127

사용하다 re.sub

import re

regex = re.compile('[^a-zA-Z]')
#First parameter is the replacement, second parameter is your input string
regex.sub('', 'ab3d*E')
#Out: 'abdE'

또는 특정 문자 집합 만 제거하려는 경우 (아포스트로피가 입력해도 괜찮을 수 있으므로 ...)

regex = re.compile('[,\.!?]') #etc.

흠, 나는 그것을 추적 할 수 있지만 공백을 제외한 모든 비 영숫자를 제거하는 패턴은 어떻습니까?
KDecker

1
컬렉션 클래스에 공간을 추가하기 만하면됩니다. 즉, ^a-zA-Z 대신에^a-zA-Z
limasxgoesto0 2014 년

개행에 대해 걱정하지 않는 한,이 경우 a-zA-Z \n. 나는 둘 다 하나로 묶을 수 있지만 원하는 동작을 사용 \w하거나 \W제공하지 않는 정규식을 찾으려고합니다 . 이 \n경우 추가해야 할 수도 있습니다 .
limasxgoesto0

Ahh, 개행 문자. 그게 내 문제가있는 곳인데, 나는 내 결과를 주어진 결과와 비교하고 있었지만 여전히 벗어났습니다. 그게 내 문제라고 생각합니다! 감사합니다 // 흠, 같은 결과를 줄 바꿈 문자로 시도해 보았습니다. 또 다른 것이 누락 된 것 같습니다. // Duhhh ... 대문자와 소문자 ... // 모든 도움을 주셔서 감사합니다. 이제 완벽하게 작동합니다!
KDecker 2014 년

48

정규식을 사용하지 않으려면 시도해 볼 수 있습니다.

''.join([i for i in s if i.isalpha()])

어떻게 참여합니까? ''.join? 의 인쇄 만 필터 객체를 가져옵니다
PirateApp

와,이게 제가 찾고 있던 것입니다. 한자, 히라가나, 가타카나 등을 고려합니다. kudos
root163

34

re.sub () 함수를 사용하여 다음 문자를 제거 할 수 있습니다.

>>> import re
>>> re.sub("[^a-zA-Z]+", "", "ABC12abc345def")
'ABCabcdef'

re.sub (패턴 일치, 문자열 교체, 검색 할 문자열)

  • "[^a-zA-Z]+" -a-zA-z가 아닌 문자 그룹을 찾습니다.
  • "" -일치하는 문자를 ""로 바꿉니다.

이렇게하면 악센트 부호가있는 문자 ãâàáéèçõ 등도 제거됩니다.
Brad Ahrens

19

시험:

s = ''.join(filter(str.isalnum, s))

이것은 문자열에서 모든 문자를 취하고 영숫자 만 유지하고 문자열을 다시 만듭니다.


1
이 답변은 더 많은 설명과 관련 문서에 대한 링크를 사용할 수 있습니다.
pdoherty926

4

가장 빠른 방법은 정규식입니다.

#Try with regex first
t0 = timeit.timeit("""
s = r2.sub('', st)

""", setup = """
import re
r2 = re.compile(r'[^a-zA-Z0-9]', re.MULTILINE)
st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+'
""", number = 1000000)
print(t0)

#Try with join method on filter
t0 = timeit.timeit("""
s = ''.join(filter(str.isalnum, st))

""", setup = """
st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+'
""",
number = 1000000)
print(t0)

#Try with only join
t0 = timeit.timeit("""
s = ''.join(c for c in st if c.isalnum())

""", setup = """
st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+'
""", number = 1000000)
print(t0)


2.6002226710006653 Method 1 Regex
5.739747313000407 Method 2 Filter + Join
6.540099570000166 Method 3 Join

0

특정 유니 코드 속성 클래스를 일치 시키려는regex 경우 PyPi 모듈 을 사용하는 것이 좋습니다 . 이 라이브러리는 특히 큰 텍스트를 처리하는 등 더 안정적인 것으로 입증되었으며 다양한 Python 버전에서 일관된 결과를 산출합니다. 최신 상태로 유지하기 만하면됩니다.

설치 ( pip intall regex또는 사용 pip3 install regex)하면 다음을 사용할 수 있습니다.

import regex
print ( regex.sub(r'\P{L}+', '', 'ABCŁąć1-2!Абв3§4“5def”') )
// => ABCŁąćАбвdef

에서 유니 코드 문자를 제외한 1 개 이상의 문자의 모든 청크를 제거합니다 text. 온라인 Python 데모를 참조하십시오 . "".join(regex.findall(r'\p{L}+', 'ABCŁąć1-2!Абв3§4“5def”'))동일한 결과를 얻기 위해 를 사용할 수도 있습니다.

Python에서는 re유니 코드 문자와 일치시키기 위해 [^\W\d_]( Match any unicode letter? ) 구문을 사용할 수 있습니다 .

따라서 문자가 아닌 모든 문자를 제거하려면 모든 문자를 일치시키고 결과를 결합 할 수 있습니다.

result = "".join(re.findall(r'[^\W\d_]', text))

또는 [^\W\d_]다음 과 일치하는 문자 이외의 모든 문자를 제거하십시오 .

result = re.sub(r'([^\W\d_])|.', r'\1', text, re.DOTALL)

온라인 정규식 데모를 참조하십시오 . 그러나 유니 코드 표준이 발전하고 있고 일치하는 문자 집합 \w이 Python 버전에 따라 달라 지기 때문에 다양한 Python 버전에서 일관성없는 결과를 얻을 수 있습니다 . regex일관된 결과를 얻으려면 PyPi 라이브러리를 사용 하는 것이 좋습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.