Dizedeki karakterlerin listesini kaldırma


217

Python dizesindeki karakterleri kaldırmak istiyorum:

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

Ama kaldırmam gereken birçok karakter var. Bir liste düşündüm

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

Ama nasıl kullanabilir listiçinde karakterleri değiştirmek için string?


6
Çeşitli çözümler ve hoş bir karşılaştırma için stackoverflow.com/questions/1919096/… adresine bakın .
Martijn de Milliano

Python'un (piller dahil olduğu söyleniyor) bu kullanım kutusunu kutudan çıkarmaması üzücü. PHP'nin str_replace işlevi bunu yapar - bir diziyi ilk argüman olarak ve bir dizeyi ikinci olarak geçirebilirsiniz ( php.net/manual/pl/function.str-replace.php ).
JustAC0der

Yanıtlar:


265

Python2 kullanıyorsanız ve girişleriniz dizelerse (unicodes değil), kesinlikle en iyi yöntem str.translate:

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

Aksi takdirde, dikkate alınması gereken aşağıdaki seçenekler vardır:

C. Konu karakterini karaktere göre yineleyin, istenmeyen karakterleri ve joinsonuç listesini atlayın :

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

(Jeneratör versiyonunun ''.join(c for c ...)daha az verimli olacağını unutmayın ).

B. Anında ve re.subboş bir dize ile düzenli bir ifade oluşturun :

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

( re.escapekarakterlerin normal ifadeyi beğenmesini ^veya kesmemesini sağlar ]).

C. Aşağıdakilerin eşleme varyantınıtranslate kullanın :

>>> 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'

Tam test kodu ve zamanlamaları:

#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)

Sonuçlar:

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

(Bir yan not olarak, bu rakam remove_chars_translate_bytesbize endüstrinin neden bu kadar uzun bir süredir Unicode'u benimsemeye isteksiz olduğuna dair bir ipucu verebilir).


1
İkinci yöntem bir hata oluşturur TypeError: translate() takes exactly one argument (2 given). Görünüşe göre bir argüman olarak dikte ediyor.
antonavy

@antonavy - 2. çözüm işe yarıyor - ancak sadece dizenin unicode değil (bunun için farklı bir çeviriye () ihtiyaç duyuluyor)
FuzzyAmi

112

Şunları kullanabilirsiniz str.translate():

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

Misal:

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

19
@ thg435: Kimse bunu istemedi, ama yine de:s.translate(dict.fromkeys(map(ord, u",!.;")))
Sven Marnach

2
Bu (ve @ PraveenGollakota'nın) eşzamanlı yanıtı , @Laura'nın istediği şeydir ve tercih edilen cevap (lar) olmalıdır.
ocaklar

7
neden python3: TypeError: translate () tam olarak bir argüman alır (2 verilir)
Gank

2
@Gank: unicode.translate()Yöntem, yöntemden farklı parametrelere sahiptir str.translate(). Unicode nesneleri için yukarıdaki açıklamadaki varyantı kullanın.
Sven Marnach

@SvenMarnach harita nedir (ord, u ",!.;"))? ve unicode için mi duruyor?
Jun711


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

Karakter ve karakter dizilerine dayanmayan benzer durumlarda
Wolf

12

Python3 kullanıyorsanız ve translateçözüm arıyorsanız - işlev değiştirildi ve şimdi 2 yerine 1 parametre alıyor.

Bu parametre, her anahtarın bulunacak karakterin Unicode ordinali (int) olduğu ve değerin değiştirildiği (bir Unicode ordinali veya anahtarı eşleştirmek için bir dize olabilir) olduğu bir tablodur (sözlük olabilir).

İşte bir kullanım örneği:

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

8

Normal ifade kullanan başka bir yaklaşım:

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

7

Neden basit bir döngü değil?

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

Ayrıca 'list' listelerini adlandırmaktan kaçının. Yerleşik işlevi geçersiz kılar list.


6

böyle bir şey kullanabilirsin

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

Bu kod benim değil ve buradan geliyor onun harika bir makale ve derinlemesine bunu yapıyor


3

Ayrıca UTF-8 aksanının kaldırılmasıyla ilgili ilginç bir konu, char'ı standart aksanlı char'a dönüştüren bir dize oluşturur:

Python unicode dizesindeki aksanları kaldırmanın en iyi yolu nedir?

konudan kod özeti:

import unicodedata

def remove_accents(input_str):
    nkfd_form = unicodedata.normalize('NFKD', input_str)
    return u"".join([c for c in nkfd_form if not unicodedata.combining(c)])

3

Belki istediğinizi başarmanın daha modern ve işlevsel bir yolu:

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

lütfen bu özel amaç için oldukça aşırı olduğunu unutmayın, ancak daha karmaşık koşullara ihtiyacınız olduğunda, filtre kullanışlı olur


Ayrıca, bunun bence çok daha pitonik olan liste kavrayışları ile de kolayca yapılabileceğini unutmayın.
ayaklandı

3

basit yol,

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)

çıktı:

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


1

Buna ne dersin - bir astar.

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

1

Bence bu yeterince basit ve yapacak!

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]

bunu yapmanın bir yolu bu. Ancak kaldırmak istediğiniz karakterlerin listesini tutmaktan yorulduysanız, bunu yinelediğiniz dizelerin sipariş numarasını kullanarak yapabilirsiniz. sipariş numarası o karakterin ascii değeridir. karakter olarak 0 için ascii numarası 48 ve küçük harf z için ascii numarası 122'dir:

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

Bugünlerde programa daldım ve şimdi tekrarlama ve değerlendirme konusunda iyi olduğumu düşünüyorum. HAHAHA. Sadece yeni yollar paylaşın:

ilk olarak, değerlendirin

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

ikinci olarak, onu geri alın

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)

Hey, küçümseme. Sadece yeni bir fikir paylaşmak istiyorum.


0

Bunun için bir çözüm düşünüyorum. İlk olarak dize girdisini bir liste olarak yapardım. Sonra liste öğelerini değiştirmek istiyorum. Sonra join komutunu kullanarak listeyi bir dize olarak döndürürüm. Kod şöyle olabilir:

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)

Bu, dizeden herhangi bir şeyi kaldıracaktır. Bunun hakkında ne düşünüyorsun?


0

İşte bir more_itertoolsyaklaşım:

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'

Burada blacklist, bulunan öğeleri bölmek , sonuçları düzleştirmek ve dizeye katılmak.


0

Python 3, tek satırlı liste anlama uygulaması.

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

Kaldırmak *%,&@! aşağıdaki dizeden:

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  
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.