Удаление списка символов в строке

Я хочу удалить символы в строке в python:

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

Но у меня есть много символов, которые мне нужно удалить. Я думал о списке

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

Но как я могу использовать list для замены символов в string?

Ответ 1

Если вы используете python2, а ваши входы - это строки (не Unicodes), абсолютно лучший метод str.translate:

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

В противном случае существуют следующие варианты:

а. Итерируйте тему char на char, опустите нежелательные символы и join в результате:

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

(Обратите внимание, что версия генератора ''.join(c for c ...) будет менее эффективной).

В. Создайте регулярное выражение "на лету" и re.sub с пустой строкой:

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

(re.escape гарантирует, что символы типа ^ или ] не нарушат регулярное выражение).

С. Используйте вариант отображения 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 может дать нам понять, почему индустрия неохотно принимает Unicode в течение такого длительного времени).

Ответ 2

Вы можете использовать str.translate():

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

Пример:

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

Ответ 3

Вы можете использовать метод translate.

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

Ответ 4

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

Ответ 5

Другой подход с использованием регулярного выражения:

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

Ответ 6

Если вы используете python3 и ищете решение translate - функция была изменена и теперь принимает 1 параметр вместо 2.

Этот параметр является таблицей (может быть словарем), где каждый ключ является порядковым номером Unicode (int) символа для поиска, а значение является заменой (может быть либо порядковым номером Unicode, либо строкой для сопоставления ключа).

Вот пример использования:

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

Ответ 7

вы можете использовать что-то вроде этого

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

Этот код не является моим собственным и происходит от здесь его отличная статья и подробно описывает это

Ответ 8

Почему бы не простой цикл?

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

Кроме того, избегайте списков списков имен. Он отменяет встроенную функцию list.

Ответ 9

Также интересная тема об удалении аккорда UTF-8 преобразует строку char в их стандартную неаккуратную char:

Каков наилучший способ удаления акцентов в строке юникода python?

извлечение кода из темы:

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

Ответ 10

Возможно, более современный и функциональный способ достижения желаемого:

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

обратите внимание, что для этой конкретной цели это довольно перебор, но как только вам понадобятся более сложные условия, фильтр пригодится

Ответ 11

простой способ,

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('[[email protected]#$%^&*()_+<>]', '', str)

выход:

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

Ответ 12

В эти дни я погружаюсь в схему, и теперь я думаю, что хорош в рекурсии и оценке. Хахаха. Просто поделитесь несколькими способами:

сначала, eval it

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)

Эй, не делай снизу. Я просто хочу поделиться какой-то новой идеей.

Ответ 13

Как насчет этого - один лайнер.

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

Ответ 14

Я думаю, что это достаточно просто и будет делать!

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 этого символа. число ascii для 0 как char равно 48, а число ascii для нижнего регистра z равно 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]

Ответ 15

Я думаю о решении для этого. Сначала я бы ввел строку в виде списка. Затем я заменил бы элементы списка. Затем, используя команду join, я верну список в виде строки. Код может быть таким:

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)

Это приведет к удалению чего-либо из строки. Что вы думаете об этом?