Menghapus daftar karakter dalam string


217

Saya ingin menghapus karakter dalam string dengan python:

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

Tapi saya punya banyak karakter yang harus saya hapus. Saya memikirkan daftar

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

Tetapi bagaimana saya bisa menggunakan listuntuk mengganti karakter di string?


6
Lihat stackoverflow.com/questions/1919096/… untuk berbagai solusi dan perbandingan yang bagus.
Martijn de Milliano

Sangat disayangkan bahwa Python (yang dikatakan datang dengan baterai termasuk) tidak menangani kasus penggunaan ini di luar kotak. Fungsi PHP str_replace melakukannya - Anda dapat melewatkan array sebagai argumen pertama dan string sebagai argumen kedua ( php.net/manual/pl/function.str-replace.php ).
JustAC0der

Jawaban:


264

Jika Anda menggunakan python2 dan input Anda berupa string (bukan unicodes), metode yang terbaik adalah str.translate:

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

Jika tidak, ada opsi berikut untuk dipertimbangkan:

A. Iterasi char subjek dengan char, hilangkan karakter yang tidak diinginkan dan joindaftar yang dihasilkan:

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

(Perhatikan bahwa versi generator ''.join(c for c ...) akan kurang efisien).

B. Buat ekspresi reguler dengan cepat dan re.subdengan string kosong:

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

( re.escapememastikan bahwa karakter suka ^atau ]tidak akan merusak ekspresi reguler).

C. Gunakan varian pemetaantranslate :

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

Kode pengujian lengkap dan timing:

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

Hasil:

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

(Sebagai catatan, angka untuk remove_chars_translate_bytesmungkin memberi kita petunjuk mengapa industri enggan mengadopsi Unicode untuk waktu yang lama).


1
Metode kedua menimbulkan kesalahan TypeError: translate() takes exactly one argument (2 given). Tampaknya dibutuhkan dikt sebagai argumen.
antonavy

@ Cantonavy - solusi 2 tidak berfungsi - tetapi hanya string yang bukan unicode (yang membutuhkan terjemahan berbeda () diperlukan
FuzzyAmi

112

Anda bisa menggunakan str.translate():

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

Contoh:

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

19
@ thg435: Tidak ada yang memintanya, tetapi:s.translate(dict.fromkeys(map(ord, u",!.;")))
Sven Marnach

2
Jawaban simultan (dan @ PraveenGollakota) ini persis seperti yang diminta @Laura dan harus menjadi jawaban yang lebih disukai.
Hobs

7
mengapa python3: TypeError: translate () mengambil tepat satu argumen (2 diberikan)
Gank

2
@Gank: unicode.translate()Metode ini memiliki parameter yang berbeda dari str.translate()metode ini. Gunakan varian dalam komentar di atas untuk objek Unicode.
Sven Marnach

@ SvenMarnach apa itu peta (ord, u ",!.;"))? dan apakah kamu berdiri untuk unicode?
Jun711


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

Berguna dalam kasus serupa yang tidak didasarkan pada karakter dan string +1
Wolf

12

Jika Anda menggunakan python3 dan mencaritranslate solusinya - fungsi berubah dan sekarang mengambil 1 parameter, bukan 2.

Parameter itu adalah sebuah tabel (bisa berupa kamus) di mana setiap kunci adalah ordinal Unicode (int) dari karakter yang akan ditemukan dan nilainya adalah penggantian (dapat berupa Unicode ordinal atau string untuk memetakan kunci ke).

Ini adalah contoh penggunaan:

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

8

Pendekatan lain menggunakan regex:

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

7

Kenapa bukan loop sederhana?

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

Juga, hindari penamaan daftar 'daftar'. Ini mengesampingkan fungsi bawaan list.


6

Anda bisa menggunakan sesuatu seperti ini

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

Kode ini bukan milik saya dan berasal dari sini artikel yang bagus dan dibahas secara mendalam



3

Mungkin cara yang lebih modern dan fungsional untuk mencapai apa yang Anda inginkan:

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

harap dicatat bahwa untuk tujuan khusus ini cukup sulit, tetapi sekali Anda membutuhkan kondisi yang lebih kompleks, filter menjadi berguna


Juga perhatikan bahwa ini bisa dengan mudah dilakukan dengan daftar pemahaman, yang jauh lebih pythonic menurut saya.
Kerusuhan

3

cara sederhana,

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)

keluaran:

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


1

Bagaimana dengan ini - satu liner.

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

1

Saya pikir ini cukup sederhana dan akan dilakukan!

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]

ini adalah salah satu cara untuk melakukannya. Tetapi jika Anda bosan menyimpan daftar karakter yang ingin Anda hapus, Anda sebenarnya dapat melakukannya dengan menggunakan nomor urut string yang Anda ulangi. nomor pesanan adalah nilai ascii dari karakter itu. angka ascii untuk 0 sebagai char adalah 48 dan angka ascii untuk huruf kecil z adalah 122 jadi:

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

Hari-hari ini saya terjun ke skema, dan sekarang saya pikir saya baik dalam pengulangan dan eval. HA HA HA. Bagikan saja beberapa cara baru:

pertama, eval it

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

kedua, ulangi saja

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)

Hei, jangan downvote. Saya hanya ingin berbagi ide baru.


0

Saya sedang memikirkan solusi untuk ini. Pertama saya akan membuat input string sebagai daftar. Maka saya akan mengganti item daftar. Kemudian dengan menggunakan perintah join, saya akan mengembalikan daftar sebagai string. Kode bisa seperti ini:

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)

Ini akan menghapus apa pun dari string. Apa pendapatmu tentang itu?


0

Berikut ini more_itertoolspendekatannya:

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'

Di sini kami membagi berdasarkan item yang ditemukan di blacklist, ratakan hasilnya dan bergabung dengan string.


0

Python 3, implementasi pemahaman daftar baris tunggal.

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

Hapus *%, & @! dari string di bawah ini:

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  
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.