Xóa danh sách các ký tự trong chuỗi


217

Tôi muốn xóa các ký tự trong một chuỗi trong python:

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

Nhưng tôi có nhiều nhân vật tôi phải loại bỏ. Tôi nghĩ về một danh sách

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

Nhưng làm thế nào tôi có thể sử dụng listđể thay thế các ký tự trong string?


6
Xem stackoverflow.com/questions/1919096/ Khắc để biết các giải pháp khác nhau và so sánh hay.
Martijn de Milliano

Thật đáng tiếc khi Python (được cho là đi kèm với pin) không xử lý trường hợp sử dụng này ra khỏi hộp. Hàm str numplace của PHP thực hiện điều đó - bạn có thể truyền một mảng làm đối số đầu tiên và một chuỗi là chuỗi thứ hai ( php.net/manual/pl/feft.str-replace.php ).
JustAC0der

Câu trả lời:


264

Nếu bạn đang sử dụng python2 và đầu vào của bạn là các chuỗi (không phải là unicodes), phương pháp hoàn toàn tốt nhất là str.translate:

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

Mặt khác, có các tùy chọn sau để xem xét:

A. Lặp lại chủ đề char bằng char, bỏ qua các ký tự không mong muốn và joindanh sách kết quả:

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

(Lưu ý rằng phiên bản máy phát điện ''.join(c for c ...)sẽ kém hiệu quả hơn).

B. Tạo một biểu thức chính quy khi đang bay và re.subvới một chuỗi trống:

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

( re.escapeđảm bảo rằng các ký tự thích ^hoặc ]sẽ không phá vỡ biểu thức chính quy).

C. Sử dụng biến thể ánh xạ củatranslate :

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

Mã và thời gian thử nghiệm đầy đủ:

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

Các kết quả:

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

(Như một lưu ý phụ, con số remove_chars_translate_bytescó thể cho chúng ta một manh mối tại sao ngành công nghiệp không muốn áp dụng Unicode trong một thời gian dài như vậy).


1
Phương pháp thứ hai làm phát sinh lỗi TypeError: translate() takes exactly one argument (2 given). Rõ ràng nó đưa dict như một cuộc tranh luận.
anton lượn sóng

@antonavy - giải pháp thứ 2 làm việc - nhưng chỉ trong những chuỗi không phải là unicode (mà dịch một khác nhau () là cần thiết)
FuzzyAmi

112

Bạn có thể sử dụng str.translate():

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

Thí dụ:

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

19
@ Jun435: Không ai yêu cầu điều này, nhưng dù sao:s.translate(dict.fromkeys(map(ord, u",!.;")))
Sven Marnach

2
Câu trả lời đồng thời (và @ PraveenGollakota) này chính xác là những gì @Laura yêu cầu và nên là câu trả lời ưa thích.
hobs

7
tại sao python3: TypeError: translate () mất chính xác một đối số (2 đã cho)
Gank

2
@Gank: unicode.translate()Phương thức có các tham số khác với str.translate()phương thức. Sử dụng biến thể trong nhận xét trên cho các đối tượng Unicode.
Sven Marnach

@SvenMarnach Bản đồ là gì (ord, u ",!.;"))? và bạn có đại diện cho unicode không?
Jun711


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

Hữu ích trong các trường hợp tương tự không dựa trên ký tự và chuỗi +1
Wolf

12

Nếu bạn đang sử dụng python3 và tìm kiếm translategiải pháp - chức năng đã được thay đổi và hiện lấy 1 tham số thay vì 2.

Tham số đó là một bảng (có thể là từ điển) trong đó mỗi khóa là thứ tự Unicode (int) của ký tự cần tìm và giá trị là sự thay thế (có thể là một thứ tự Unicode hoặc một chuỗi để ánh xạ khóa tới).

Dưới đây là một ví dụ sử dụng:

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

8

Một cách tiếp cận khác sử dụng regex:

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

7

Tại sao không phải là một vòng lặp đơn giản?

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

Ngoài ra, tránh đặt tên danh sách 'danh sách'. Nó ghi đè chức năng tích hợp list.


6

bạn có thể sử dụng một cái gì đó như thế này

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

Mã này không phải của riêng tôi và xuất phát từ đây, đây là một bài viết tuyệt vời và chuyên sâu thực hiện điều này



3

Có lẽ một cách hiện đại và chức năng hơn để đạt được những gì bạn muốn:

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

xin lưu ý rằng với mục đích cụ thể này, nó khá là quá mức, nhưng một khi bạn cần các điều kiện phức tạp hơn, bộ lọc trở nên tiện dụng


Cũng lưu ý rằng điều này có thể dễ dàng được thực hiện với sự hiểu biết danh sách, đó là cách pythonic nhiều hơn theo ý kiến ​​của tôi.
bạo loạn

3

cách đơn giản,

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)

đầu ra:

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


1

Làm thế nào về điều này - một lót.

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

1

Tôi nghĩ rằng điều này là đủ đơn giản và sẽ làm!

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]

đây là một cách để làm điều đó Nhưng nếu bạn cảm thấy mệt mỏi với việc giữ một danh sách các ký tự mà bạn muốn xóa, bạn thực sự có thể làm điều đó bằng cách sử dụng số thứ tự của các chuỗi bạn lặp qua. số thứ tự là giá trị ascii của ký tự đó. số ascii cho 0 dưới dạng char là 48 và số ascii cho chữ thường z là 122 vì vậy:

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

Những ngày này tôi đang đi sâu vào kế hoạch, và bây giờ tôi nghĩ rằng tôi rất giỏi trong việc đệ quy và đánh giá. HAHAHA. Chỉ cần chia sẻ một số cách mới:

đầu tiên, đánh giá nó

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

thứ hai, tái diễn 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, đừng downvote. Tôi chỉ muốn chia sẻ một số ý tưởng mới.


0

Tôi đang suy nghĩ về một giải pháp cho việc này. Đầu tiên tôi sẽ làm cho đầu vào chuỗi như một danh sách. Sau đó, tôi sẽ thay thế các mục của danh sách. Sau đó thông qua sử dụng lệnh nối, tôi sẽ trả về danh sách dưới dạng chuỗi. Mã có thể như thế này:

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)

Điều này sẽ loại bỏ bất cứ điều gì từ chuỗi. Bạn nghĩ gì về điều này?


0

Đây là một more_itertoolscách tiếp cận:

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'

Ở đây chúng tôi chia ra các mục được tìm thấy trong blacklist, làm phẳng kết quả và tham gia chuỗi.


0

Python 3, thực hiện hiểu danh sách dòng đơn.

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

Tẩy *%,&@! từ chuỗi bên dưới:

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  
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.