문자열에서 문자 목록 제거


217

파이썬에서 문자열의 문자를 제거하고 싶습니다.

string.replace(',', '').replace("!", '').replace(":", '').replace(";", '')...

그러나 제거해야 할 문자가 많이 있습니다. 나는 목록에 대해 생각했다

list = [',', '!', '.', ';'...]

그러나를 사용 list하여 문자를 바꾸려면 string어떻게 해야 합니까?


6
다양한 솔루션과 훌륭한 비교는 stackoverflow.com/questions/1919096/… 을 참조하십시오 .
Martijn de Milliano

파이썬 (배터리가 포함되어 있다고 함) 이이 유스 케이스를 즉시 처리하지 못하는 것은 유감입니다. PHP의 str_replace 함수는 배열을 첫 번째 인수로, 문자열을 두 번째 인수로 전달할 수 있습니다 ( php.net/manual/pl/function.str-replace.php ).
JustAC0der

답변:


265

python2를 사용하고 입력이 문자열 (유니 코드가 아닌) 인 경우 가장 좋은 방법은 str.translate다음과 같습니다.

>>> chars_to_remove = ['.', '!', '?']
>>> subj = 'A.B!C?'
>>> subj.translate(None, ''.join(chars_to_remove))
'ABC'

그렇지 않으면 고려해야 할 옵션이 있습니다.

A. 제목별로 char을 반복하고 원하지 않는 문자와 join결과 목록을 생략 하십시오.

>>> sc = set(chars_to_remove)
>>> ''.join([c for c in subj if c not in sc])
'ABC'

(제너레이터 버전의 ''.join(c for c ...)효율성이 떨어집니다.)

B. re.sub빈 문자열 을 사용하여 즉석에서 정규 표현식을 만듭니다 .

>>> import re
>>> rx = '[' + re.escape(''.join(chars_to_remove)) + ']'
>>> re.sub(rx, '', subj)
'ABC'

( re.escape문자 가 정규 표현식 과 같 ^거나 ]깨지지 않도록합니다).

C. 다음의 매핑 변형을translate 사용하십시오 .

>>> chars_to_remove = [u'δ', u'Γ', u'ж']
>>> subj = u'AжBδCΓ'
>>> dd = {ord(c):None for c in chars_to_remove}
>>> subj.translate(dd)
u'ABC'

전체 테스트 코드 및 타이밍 :

#coding=utf8

import re

def remove_chars_iter(subj, chars):
    sc = set(chars)
    return ''.join([c for c in subj if c not in sc])

def remove_chars_re(subj, chars):
    return re.sub('[' + re.escape(''.join(chars)) + ']', '', subj)

def remove_chars_re_unicode(subj, chars):
    return re.sub(u'(?u)[' + re.escape(''.join(chars)) + ']', '', subj)

def remove_chars_translate_bytes(subj, chars):
    return subj.translate(None, ''.join(chars))

def remove_chars_translate_unicode(subj, chars):
    d = {ord(c):None for c in chars}
    return subj.translate(d)

import timeit, sys

def profile(f):
    assert f(subj, chars_to_remove) == test
    t = timeit.timeit(lambda: f(subj, chars_to_remove), number=1000)
    print ('{0:.3f} {1}'.format(t, f.__name__))

print (sys.version)
PYTHON2 = sys.version_info[0] == 2

print ('\n"plain" string:\n')

chars_to_remove = ['.', '!', '?']
subj = 'A.B!C?' * 1000
test = 'ABC' * 1000

profile(remove_chars_iter)
profile(remove_chars_re)

if PYTHON2:
    profile(remove_chars_translate_bytes)
else:
    profile(remove_chars_translate_unicode)

print ('\nunicode string:\n')

if PYTHON2:
    chars_to_remove = [u'δ', u'Γ', u'ж']
    subj = u'AжBδCΓ'
else:
    chars_to_remove = ['δ', 'Γ', 'ж']
    subj = 'AжBδCΓ'

subj = subj * 1000
test = 'ABC' * 1000

profile(remove_chars_iter)

if PYTHON2:
    profile(remove_chars_re_unicode)
else:
    profile(remove_chars_re)

profile(remove_chars_translate_unicode)

결과 :

2.7.5 (default, Mar  9 2014, 22:15:05) 
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)]

"plain" string:

0.637 remove_chars_iter
0.649 remove_chars_re
0.010 remove_chars_translate_bytes

unicode string:

0.866 remove_chars_iter
0.680 remove_chars_re_unicode
1.373 remove_chars_translate_unicode

---

3.4.2 (v3.4.2:ab2c023a9432, Oct  5 2014, 20:42:22) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]

"plain" string:

0.512 remove_chars_iter
0.574 remove_chars_re
0.765 remove_chars_translate_unicode

unicode string:

0.817 remove_chars_iter
0.686 remove_chars_re
0.876 remove_chars_translate_unicode

부수적으로,에 대한 수치는 remove_chars_translate_bytes왜 업계가 오랫동안 유니 코드를 채택하기를 꺼려했는지에 대한 단서를 제공 할 수 있습니다.


1
두 번째 방법은 오류를 발생시킵니다 TypeError: translate() takes exactly one argument (2 given). 분명히 그것은 dict를 인수로 취합니다.
antonavy

@antonavy-두 번째 솔루션은 작동하지만 문자열 만 유니 코드가 아닙니다 (다른 translate ()가 필요함)
FuzzyAmi

112

당신은 사용할 수 있습니다 str.translate():

s.translate(None, ",!.;")

예:

>>> s = "asjo,fdjk;djaso,oio!kod.kjods;dkps"
>>> s.translate(None, ",!.;")
'asjofdjkdjasooiokodkjodsdkps'

19
@ thg435 : 아무도 이것을 요구하지 않았지만 어쨌든 :s.translate(dict.fromkeys(map(ord, u",!.;")))
Sven Marnach

2
이 (그리고 @PraveenGollakota의) 동시 답변 은 @Laura가 요청한 것과 정확히 일치해야합니다.
호브

7
왜 python3 : TypeError : translate ()는 정확히 하나의 인수를 취합니다 (2 주어진)
Gank

2
@Gank : unicode.translate()메소드와 다른 매개 변수가 str.translate()있습니다. 유니 코드 객체에 대해서는 위 주석에서 변형을 사용하십시오.
Sven Marnach

@SvenMarnach map (ord, u ",!.;"))은 무엇입니까? 그리고 유니 코드를 의미합니까?
Jun711


16
''.join(c for c in myString if not c in badTokens)

문자와 문자열을 기반으로하지 않는 유사한 경우에 유용 +1
Wolf

12

python3 을 사용 하고 translate솔루션을 찾는 경우 기능이 변경되어 이제 2 대신 1 매개 변수를 사용합니다.

이 매개 변수는 각 키가 찾을 문자의 유니 코드 서수 (int) 인 테이블 (사전 일 수 있음)이며 값은 대체입니다 (유니 코드 서수 또는 키를 맵핑하는 문자열 일 수 있음).

사용 예는 다음과 같습니다.

>>> list = [',', '!', '.', ';']
>>> s = "This is, my! str,ing."
>>> s.translate({ord(x): '' for x in list})
'This is my string'

8

정규식을 사용하는 또 다른 접근법 :

''.join(re.split(r'[.;!?,]', s))

7

단순한 루프가 아닌가?

for i in replace_list:
    string = string.replace(i, '')

또한 목록의 이름을 'list'로 지정하지 마십시오. 내장 함수를 대체합니다 list.


6

이런 식으로 사용할 수 있습니다

def replace_all(text, dic):
  for i, j in dic.iteritems():
    text = text.replace(i, j)
  return text

이 코드는 내 코드가 아니며 여기 에서 훌륭한 기사로 제공 되며이 작업을 깊이있게 설명합니다



3

아마도 당신이 원하는 것을 성취하는 더 현대적이고 기능적인 방법 일 것입니다 :

>>> subj = 'A.B!C?'
>>> list = set([',', '!', '.', ';', '?'])
>>> filter(lambda x: x not in list, subj)
'ABC'

이 특정 목적을 위해서는 상당히 과잉이지만 더 복잡한 조건이 필요하면 필터가 편리합니다.


또한 이것은 목록 이해를 통해 쉽게 수행 할 수 있다는 점에 유의하십시오.
폭동 :

3

간단한 방법으로

import re
str = 'this is string !    >><< (foo---> bar) @-tuna-#   sandwich-%-is-$-* good'

// condense multiple empty spaces into 1
str = ' '.join(str.split()

// replace empty space with dash
str = str.replace(" ","-")

// take out any char that matches regex
str = re.sub('[!@#$%^&*()_+<>]', '', str)

산출:

this-is-string--foo----bar--tuna---sandwich--is---good


1

이건 어때요-하나의 라이너.

reduce(lambda x,y : x.replace(y,"") ,[',', '!', '.', ';'],";Test , ,  !Stri!ng ..")

1

나는 이것이 충분히 간단하다고 생각합니다!

list = [",",",","!",";",":"] #the list goes on.....

theString = "dlkaj;lkdjf'adklfaj;lsd'fa'dfj;alkdjf" #is an example string;
newString="" #the unwanted character free string
for i in range(len(TheString)):
    if theString[i] in list:
        newString += "" #concatenate an empty string.
    else:
        newString += theString[i]

이것이 한 가지 방법입니다. 그러나 제거하려는 문자 목록을 유지하는 데 지치면 실제로 반복하는 문자열의 순서 번호를 사용하여 제거 할 수 있습니다. 주문 번호는 해당 문자의 ASCII 값입니다. 문자로서 0에 대한 ASCII 숫자는 48이고 소문자 z에 대한 ASCII 숫자는 122입니다.

theString = "lkdsjf;alkd8a'asdjf;lkaheoialkdjf;ad"
newString = ""
for i in range(len(theString)):
     if ord(theString[i]) < 48 or ord(theString[i]) > 122: #ord() => ascii num.
         newString += ""
     else:
        newString += theString[i]

0

요즘 나는 계획에 뛰어 들고 있으며, 지금은 되풀이와 평가에 능숙하다고 생각합니다. 하하하. 몇 가지 새로운 방법을 공유하십시오.

먼저, 평가

print eval('string%s' % (''.join(['.replace("%s","")'%i for i in replace_list])))

둘째, 재귀

def repn(string,replace_list):
    if replace_list==[]:
        return string
    else:
        return repn(string.replace(replace_list.pop(),""),replace_list)

print repn(string,replace_list)

이봐 요, 공감하지 마세요. 새로운 아이디어를 나누고 싶습니다.


0

나는 이것에 대한 해결책을 생각하고 있습니다. 먼저 문자열 입력을 목록으로 만듭니다. 그런 다음 목록의 항목을 바꿉니다. 그런 다음 join 명령을 사용하여 list를 문자열로 반환합니다. 코드는 다음과 같습니다.

def the_replacer(text):
    test = []    
    for m in range(len(text)):
        test.append(text[m])
        if test[m]==','\
        or test[m]=='!'\
        or test[m]=='.'\
        or test[m]=='\''\
        or test[m]==';':
    #....
            test[n]=''
    return ''.join(test)

이것은 문자열에서 아무것도 제거합니다. 그것에 대해 어떻게 생각하세요?


0

more_itertools접근 방식 은 다음과 같습니다 .

import more_itertools as mit


s = "A.B!C?D_E@F#"
blacklist = ".!?_@#"

"".join(mit.flatten(mit.split_at(s, pred=lambda x: x in set(blacklist))))
# 'ABCDEF'

여기에서 찾은 항목을 분할 blacklist하고 결과를 평평하게하고 문자열을 조인합니다.


0

Python 3, 단일 행 목록 이해 구현.

from string import ascii_lowercase # 'abcdefghijklmnopqrstuvwxyz'
def remove_chars(input_string, removable):
  return ''.join([_ for _ in input_string if _ not in removable])

print(remove_chars(input_string="Stack Overflow", removable=ascii_lowercase))
>>> 'S O'

0

* %, & @를 제거하십시오! 아래 문자열에서 :

s = "this is my string,  and i will * remove * these ** %% "
new_string = s.translate(s.maketrans('','','*%,&@!'))
print(new_string)

# output: this is my string  and i will  remove  these  
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.