Удалить определенные символы из строки в Python - PullRequest
456 голосов
/ 15 октября 2010

Я пытаюсь удалить определенные символы из строки, используя Python.Это код, который я использую прямо сейчас.К сожалению, кажется, что ничего не делает со строкой.

for char in line:
    if char in " ?.!/;:":
        line.replace(char,'')

Как мне сделать это правильно?

Ответы [ 27 ]

555 голосов
/ 15 октября 2010

Строки в Python неизменны (не может быть изменено).Из-за этого line.replace(...) просто создает новую строку, а не заменяет старую.Вам нужно перепривязать (присвоить) его line, чтобы эта переменная приняла новое значение без удаления этих символов.

Кроме того, способ, которым вы это делаете, идетбыть немного медленным, относительно.Вероятно, это будет немного смущать опытных питонаторов, которые увидят дважды вложенную структуру и на мгновение подумают, что происходит нечто более сложное.

Начиная с Python 2.6 и более новых версий Python 2.x*, вместо этого вы можете использовать str.translate, (но читайте дальше для различий Python 3):

line = line.translate(None, '!@#$')

или замена регулярного выражения на re.sub

import re
line = re.sub('[!@#$]', '', line)

Символы, заключенные в скобки, составляют класс символов .Любые символы в line, которые находятся в этом классе, заменяются вторым параметром на sub: пустой строкой.

В Python 3 строки - это Unicode.Вам придется переводить немного по-другому.kevpie упоминает это в комментарии к одному из ответов, и это отмечается в документации для str.translate.

При вызове метода translate дляСтрока Unicode, вы не можете передать второй параметр, который мы использовали выше.Вы также не можете передать None в качестве первого параметра или даже таблицу перевода из string.maketrans.Вместо этого вы передаете словарь в качестве единственного параметра.Этот словарь отображает порядковые значения символов (т. Е. Результат вызова ord для них) в порядковые значения символов, которые должны их заменить, или, что нам полезно,None, чтобы указать, что они должны быть удалены.

Таким образом, чтобы выполнить вышеупомянутый танец со строкой Unicode, вы бы назвали что-то вроде

translation_table = dict.fromkeys(map(ord, '!@#$'), None)
unicode_line = unicode_line.translate(translation_table)

Здесь dict.fromkeys и map используются для краткой генерации словаря, содержащего

{ord('!'): None, ord('@'): None, ...}

Еще проще, так как другой ответ помещает его , создайте словарь на месте:

unicode_line = unicode_line.translate({ord(c): None for c in '!@#$'})

* для совместимости с более ранними Pythons, вы можете создать «нулевую» таблицу перевода для передачи вместо None:

import string
line = line.translate(string.maketrans('', ''), '!@#$')

Здесь string.maketrans используется для создания таблицы перевода , которая представляет собой просто строку, содержащую символы с порядковыми значениями от 0 до 255.

195 голосов
/ 15 октября 2010

Я упускаю здесь точку или это просто следующее:

>>> string = "ab1cd1ef"
>>> string.replace("1","")
'abcdef'
>>>

Поместите это в цикл:

>>>
>>> a = "a!b@c#d$"
>>> b = "!@#$"
>>> for char in b:
...     a = a.replace(char,"")
...
>>> print a
abcd
>>>
39 голосов
/ 15 октября 2010
>>> line = "abc#@!?efg12;:?"
>>> ''.join( c for c in line if  c not in '?:!/;' )
'abc#@efg12'
22 голосов
/ 26 сентября 2017

Easy peasy с re.sub в Python 3.5

re.sub('\ |\?|\.|\!|\/|\;|\:', '', line)

Пример

>>> import re

>>> line = 'Q: Do I write ;/.??? No!!!'

>>> re.sub('\ |\?|\.|\!|\/|\;|\:', '', line)
'QDoIwriteNo'

Объяснение

В регулярные выражения (регулярное выражение), | - это логическое ИЛИ, а \ экранирует пробелы и специальные символы, которые могут быть фактическими командами регулярного выражения.sub означает замену.

19 голосов
/ 26 января 2014

Для обратного требования только , разрешающего определенные символы в строке, вы можете использовать регулярные выражения с оператором дополнения набора [^ABCabc]. Например, чтобы удалить все, кроме букв ascii, цифр и дефиса:

>>> import string
>>> import re
>>>
>>> phrase = '  There were "nine" (9) chick-peas in my pocket!!!      '
>>> allow = string.letters + string.digits + '-'
>>> re.sub('[^%s]' % allow, '', phrase)

'Therewerenine9chick-peasinmypocket'

С документация по регулярным выражениям python :

Символы, которые не находятся в пределах диапазона, могут быть сопоставлены путем дополнения набор. Если первый символ набора '^', все символы которые не в наборе будут сопоставлены. Например, [^5] будет соответствовать любой символ, кроме «5», и [^^] будет соответствовать любому символу, кроме '^'. ^ не имеет особого значения, если это не первый символ в установлен.

18 голосов
/ 14 декабря 2011

У аскера почти было это.Как и большинство вещей в Python, ответ проще, чем вы думаете.

>>> line = "H E?.LL!/;O:: "  
>>> for char in ' ?.!/;:':  
...  line = line.replace(char,'')  
...
>>> print line
HELLO

Вам не нужно выполнять вложенные циклы if / for, но вам НЕОБХОДИМО проверять каждый символ отдельно.

14 голосов
/ 15 октября 2010
line = line.translate(None, " ?.!/;:")
10 голосов
/ 08 октября 2015
>>> s = 'a1b2c3'
>>> ''.join(c for c in s if c not in '123')
'abc'
8 голосов
/ 15 октября 2010

Строки неизменны в Python.Метод replace возвращает новую строку после замены.Попробуйте:

for char in line:
    if char in " ?.!/;:":
        line = line.replace(char,'')
6 голосов
/ 01 января 2017

Я был удивлен, что никто еще не рекомендовал использовать встроенную функцию filter .

    import operator
    import string # only for the example you could use a custom string

    s = "1212edjaq"

Скажем, мы хотим отфильтровать все, что не является числом.Использование встроенного метода фильтра «... эквивалентно выражению генератора (элемент для элемента в итерируемой функции (элемент))» [ Python 3 Builtins: Фильтр ]

    sList = list(s)
    intsList = list(string.digits)
    obj = filter(lambda x: operator.contains(intsList, x), sList)))

В Python 3 это возвращает

    >>  <filter object @ hex>

Чтобы получить печатную строку,

    nums = "".join(list(obj))
    print(nums)
    >> "1212"

Я не уверен, как фильтр ранжируется в терминахэффективности, но это полезно знать, как использовать при выполнении списка списков и тому подобное.

ОБНОВЛЕНИЕ

Логически, поскольку фильтр работает, вы также можете использовать понимание списка и из того, что я прочиталПредполагается, что он будет более эффективным, потому что лямбды являются менеджерами хедж-фондов Уолл-стрит в мире функций программирования.Еще одним плюсом является то, что это однострочник, который не требует импорта.Например, используя ту же строку 's', определенную выше,

      num = "".join([i for i in s if i.isdigit()])

Вот и все.Возвращаемым будет строка всех символов, которые являются цифрами в исходной строке.

Если у вас есть определенный список допустимых / недопустимых символов, вам нужно только отрегулировать часть «если» в понимании списка.

      target_chars = "".join([i for i in s if i in some_list]) 

или, альтернативно,

      target_chars = "".join([i for i in s if i not in some_list])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...