문자열에서 특수 문자, 문장 부호 및 공백을 모두 제거하십시오.


236

문자와 숫자 만 가질 수 있도록 문자열에서 모든 특수 문자, 문장 부호 및 공백을 제거해야합니다.

답변:


351

이것은 정규 표현식없이 수행 할 수 있습니다 :

>>> string = "Special $#! characters   spaces 888323"
>>> ''.join(e for e in string if e.isalnum())
'Specialcharactersspaces888323'

당신은 사용할 수 있습니다 str.isalnum:

S.isalnum() -> bool

Return True if all characters in S are alphanumeric
and there is at least one character in S, False otherwise.

정규식 사용을 고집하면 다른 해결책이 좋습니다. 그러나 정규 표현식을 사용하지 않고 수행 할 수 있다면 가장 좋은 방법입니다.


7
대체로 정규 표현식을 사용하지 않는 이유는 무엇입니까?
Chris Dutrow

@ChrisDutrow 정규식 느린 파이썬 문자열보다 내장의 기능이있다
디에고 바로

문자열이 유니 코드 인 경우에만 작동합니다 . 그렇지 않으면 'str'객체에 'isalnum' 'isnumeric'속성이없는 것처럼 불평합니다.
NeoJi

10
사실이 아닌 것을 제외하고 @DiegoNavarro, 나는 isalnum()정규식과 정규식 버전을 벤치마킹 했고 정규식은 50-75 % 더 빠릅니다
Francisco Couzo

2
"8 비트 문자열의 경우이 방법은 로캘에 따라 다릅니다."! 따라서 정규식 대안이 엄격히 좋습니다!
Antti Haapala

232

문자 나 숫자가 아닌 문자열과 일치하는 정규식은 다음과 같습니다.

[^A-Za-z0-9]+

정규식 대체를 수행하는 Python 명령은 다음과 같습니다.

re.sub('[^A-Za-z0-9]+', '', mystring)

10
키스 : 단순 바보 유지! 이것은 정규식이 아닌 솔루션보다 짧고 읽기가 쉽고 빠를 수도 있습니다. (그러나 +효율을 조금 높이기 위해 수량
화기

1
또한 단어 사이의 공백 인 "위대한 장소"-> "위대한 장소"를 제거합니다. 그것을 피하는 방법?
Reihan_amn

5
@Reihan_amn 간단히 정규 표현식에 공백을 추가하면 다음과 같이됩니다.[^A-Za-z0-9 ]+
ostroon

1
@ Andy-white 정답에 공백을 추가 할 수 있습니까? 우주는 특별한 성격이 아니다 ...
Ufos

3
나는 이것이 á , ö , ñ 등과 같은 다른 언어의 수정 된 문자로는 작동하지 않는다고 생각합니다 . 맞습니까? 그렇다면 어떻게 정규 표현식이 될까요?
HuLu ViCa

50

더 짧은 방법 :

import re
cleanString = re.sub('\W+','', string )

단어와 숫자 사이에 공백을 원하면 ''를 '


3
_가 \ w에 있고이 질문의 맥락에서 특별한 문자 인 것을 제외하고.
kkurian

상황에 따라 다릅니다-밑줄은 파일 이름 및 기타 식별자에 매우 유용합니다. 필자는 파일을 특수 문자로 처리하지 않고 위생 처리 된 공간으로 취급합니다. 일반적 으로이 방법을 직접 사용합니다.
Echelon

1
r'\W+'-주제에서 약간 벗어난 (그리고 매우 비현실적이지만) 모든 정규 표현식 패턴이 원시 문자열

2
이 절차는 밑줄 (_)을 특수 문자로 취급하지 않습니다.
Md. Sabbir Ahmed

30

이것을 본 후, 나는 가장 적은 시간에 실행되는 것을 찾아서 제공된 답변을 확장하는 데 관심이 있었으므로 제안 된 답변 중 일부를 timeit두 개의 예제 문자열 과 비교 하여 확인했습니다 .

  • string1 = 'Special $#! characters spaces 888323'
  • string2 = 'how much for the maple syrup? $20.99? That s ricidulous!!!'

실시 예 1

'.join(e for e in string if e.isalnum())

  • string1 -결과 : 10.7061979771
  • string2 -결과 : 7.78372597694

실시 예 2

import re re.sub('[^A-Za-z0-9]+', '', string)

  • string1 -결과 : 7.10785102844
  • string2 -결과 : 4.12814903259

실시 예 3

import re re.sub('\W+','', string)

  • string1 -결과 : 3.11899876595
  • string2 -결과 : 2.78014397621

위의 결과는 평균에서 다음과 같이 가장 낮은 결과를 얻었습니다 repeat(3, 2000000)

예 3예 1 보다 3 배 더 빠를 수 있습니다 .


@kkurian 내 대답의 시작 부분을 읽으면 위의 제안 된 솔루션을 비교 한 것입니다. 당신은 ... 원래 응답에 코멘트를 할 수 있습니다 stackoverflow.com/a/25183802/2560922
mbeacom

오, 당신이 어디로 가는지 봅니다. 끝난!
kkurian

1
큰 말뭉치를 다룰 때 예제 3을 고려해야합니다.
HARSH NILESH PATHAK

유효한! 주목 해 주셔서 감사합니다.
mbeacom

내 답변을 비교할 수 있습니까''.join([*filter(str.isalnum, string)])
Grijesh Chauhan

22

파이썬 2. *

난 그냥 filter(str.isalnum, string)작동 생각

In [20]: filter(str.isalnum, 'string with special chars like !,#$% etcs.')
Out[20]: 'stringwithspecialcharslikeetcs'

파이썬 3. *

Python3에서 filter( )함수는 위와 달리 문자열 대신 반복 가능한 객체를 반환합니다. itertable에서 문자열을 얻으려면 다시 결합해야합니다.

''.join(filter(str.isalnum, string)) 

또는 list결합 사용 에 전달 하기 ( 확실하지 않지만 조금 빠를 수 있음 )

''.join([*filter(str.isalnum, string)])

참고 : Python> = 3.5 에서 [*args]유효한 포장 풀기


4
@Alexey correct, python3 map에서 filter, reduce 대신 itertable 객체를 반환합니다. 여전히 Python3 이상에서는 허용 된 답변보다 선호합니다 ''.join(filter(str.isalnum, string)) (또는 조인 사용 목록을 전달 ''.join([*filter(str.isalnum, string)])).
Grijesh Chauhan

나는 적어도 읽을 ''.join(filter(str.isalnum, string))만한 것이 확실하지 않다 filter(str.isalnum, string). 이것이 실제로 Pythreenic입니까 (예, 사용할 수 있습니다)이 작업을 수행합니까?
프롤레타리아

1
요점은 @TheProletariat 단지filter(str.isalnum, string) 로 Python3에서 문자열을 반환하지 않는 filter( )파이썬 2와 달리 인수 유형보다는 반복자를 반환 Python3에 +.
Grijesh 차우

@GrijeshChauhan, Python2 및 Python3 권장 사항을 모두 포함하도록 답변을 업데이트해야한다고 생각합니다.
mwfearnley

18
#!/usr/bin/python
import re

strs = "how much for the maple syrup? $20.99? That's ricidulous!!!"
print strs
nstr = re.sub(r'[?|$|.|!]',r'',strs)
print nstr
nestr = re.sub(r'[^a-zA-Z0-9 ]',r'',nstr)
print nestr

더 많은 특수 문자를 추가 할 수 있으며 ''로 대체됩니다. 즉, 제거되지 않습니다.


16

다른 사람들이 정규식을 사용하는 것과 달리, 내가 원하지 않는 것을 명시 적으로 열거하는 대신 내가 원하지 않는 모든 문자를 제외하려고합니다 .

예를 들어 'a에서 z'까지의 문자 (대문자 및 소문자)와 숫자 만 원하면 다른 모든 것을 제외합니다.

import re
s = re.sub(r"[^a-zA-Z0-9]","",s)

이것은 "숫자가 아닌 모든 문자 또는 빈 문자열로 'a ~ z'또는 'A ~ Z'범위의 문자를 대체합니다"를 의미합니다.

실제로 ^정규 표현식의 첫 번째 위치에 특수 문자를 삽입 하면 부정이 발생합니다.

추가 팁 : 결과 를 소문자 로 사용해야하는 경우 대문자를 찾지 않는 한 정규식을 더 빠르고 쉽게 만들 수 있습니다.

import re
s = re.sub(r"[^a-z0-9]","",s.lower())

9

정규식을 사용하고 2 ~ 3 준비가 된 유니 코드 코 그니 넌트 2.x 코드가 필요하다고 가정하면 :

>>> import re
>>> rx = re.compile(u'[\W_]+', re.UNICODE)
>>> data = u''.join(unichr(i) for i in range(256))
>>> rx.sub(u'', data)
u'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\xaa\xb2 [snip] \xfe\xff'
>>>


6

가장 일반적인 접근 방식은 모든 단일 문자를 분류하는 unicodedata 테이블의 '범주'를 사용하는 것입니다. 예를 들어 다음 코드는 해당 범주를 기준으로 인쇄 가능한 문자 만 필터링합니다.

import unicodedata
# strip of crap characters (based on the Unicode database
# categorization:
# http://www.sql-und-xml.de/unicode-database/#kategorien

PRINTABLE = set(('Lu', 'Ll', 'Nd', 'Zs'))

def filter_non_printable(s):
    result = []
    ws_last = False
    for c in s:
        c = unicodedata.category(c) in PRINTABLE and c or u'#'
        result.append(c)
    return u''.join(result).replace(u'#', u' ')

모든 관련 카테고리는 위의 지정된 URL을 확인하십시오. 구두점 카테고리별로 필터링 할 수도 있습니다.


$각 줄의 끝에는 무엇이 있습니까?
John Machin

복사 및 붙여 넣기 문제라면 해결해야합니까?
Olli

5

string.punctuation에는 다음 문자가 포함됩니다.

'! "# $ % & \'() * +,-. / :; <=>? @ [\] ^ _`{|} ~ '

번역 및 maketrans 함수를 사용하여 문장 부호를 빈 값에 매핑 할 수 있습니다 (대체).

import string

'This, is. A test!'.translate(str.maketrans('', '', string.punctuation))

산출:

'This is A test'

4

번역 사용 :

import string

def clean(instr):
    return instr.translate(None, string.punctuation + ' ')

주의 사항 : ASCII 문자열에서만 작동합니다.


버전 차이? 나는 TypeError: translate() takes exactly one argument (2 given)py3.4를 얻는다
matt wilkie

1
import re
my_string = """Strings are amongst the most popular data types in Python. We can create the strings by enclosing characters in quotes. Python treats single quotes the 

큰 따옴표와 동일합니다. "" "

# if we need to count the word python that ends with or without ',' or '.' at end

count = 0
for i in text:
    if i.endswith("."):
        text[count] = re.sub("^([a-z]+)(.)?$", r"\1", i)
    count += 1
print("The count of Python : ", text.count("python"))

0
import re
abc = "askhnl#$%askdjalsdk"
ddd = abc.replace("#$%","")
print (ddd)

그리고 당신은 당신의 결과를

'askhnlaskdjalsdk


4
잠깐만 ... 가져 re왔지만 사용하지는 않았습니다. 귀하의 replace기준이 특정한 문자열을 사용할 수 있습니다. 만약 당신의 문자열이 abc = "askhnl#$%!askdjalsdk"무엇입니까? #$%패턴 이외의 다른 것으로는 작동하지 않을 것이라고 생각합니다 . 그것을 조정하고 싶을지도 모른다
JChao

0

문장 부호, 숫자 및 특수 문자 제거

예 :-

여기에 이미지 설명을 입력하십시오

암호

combi['tidy_tweet'] = combi['tidy_tweet'].str.replace("[^a-zA-Z#]", " ") 

결과:- 여기에 이미지 설명을 입력하십시오

감사 :)

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