Удаление определенных символов из строки в Python

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

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

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

Комментарии к вопросу (5)
Решение

Строки в 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 '!@#$'})

* Для совместимости с более ранними версиями Python, вы можете создать "null" таблицу перевода для передачи вместо None:

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

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

Комментарии (7)

Я что-то недопонимаете, или это просто следующее:

``питон строка = "и ab1cd1ef и" строку.заменить (на"1" и" Ну и")

строки для печати

результат: "по абвгде и"

``

Положить его в цикле:

``puthon а = "а!б@с#д&Я$; Б = и"!@#$&и" для гольца в б: а = а.заменить(Чара, и" и")

распечатать

результат: Любовь"и

``

Комментарии (3)
>>> line = "abc#@!?efg12;:?"
>>> ''.join( c for c in line if  c not in '?:!/;' )
'abc#@efg12'
Комментарии (3)
re.sub('\ |\?|\.|\!|\/|\;|\:', '', line)

Пример ###

>>> import re

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

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

Объяснение

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

Комментарии (0)

Для обратной требование только позволяет некоторые символы в строке, вы можете использовать регулярные выражения с оператором дополнением [^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', и [ ^ ^ ] соответствует любому символу, за исключением '^'.^` не имеет особого смысла, если это не первый персонаж набор.

Комментарии (0)

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

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

Вы Don'т придется делать вложенные if/for цикл вещь, но вы должны проверить каждый символ в отдельности.

Комментарии (3)
line = line.translate(None, " ?.!/;:")
Комментарии (2)
>>> s = 'a1b2c3'
>>> ''.join(c for c in s if c not in '123')
'abc'
Комментарии (1)

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

for char in line:
    if char in " ?.!/;:":
        line = line.replace(char,'')
Комментарии (3)

Я был удивлен, что никто еще не рекомендовал использовать встроенный <б>фильтр</б> функция.

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

    s = "1212edjaq"

Скажем, мы хотим отфильтровать все, что это'т ряд. Используя фильтр встроенный способ " и...эквивалентный генератор выражение (элемент для элемента в массиве, если функция(элемент)), что" [<а href="и https://docs.python.org/3/library/functions.html#filter">питон 3 примитивы: <и>фильтр</а></а>]

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

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

    >>  

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

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

Я не уверен, как <б>фильтр</б> ряды с точки зрения эффективности, но это хорошая вещь, чтобы знать, как использовать, когда делаешь список осмысленностей и такие.

Обновление

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

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

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

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

      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])
Комментарии (1)

Используя фильтр, Вы'd только одна строка

line = filter(lambda char: char not in " ?.!/;:", line)

Это относится к строке, как и проверяет, повторяемое каждый персонаж при лямбда возвращает true:

помощь(фильтр) помощь на встроенную функцию фильтра в модуле строение:

фильтр(...) фильтр(функция или нет, последовательность) -> Список, кортеж, строка

возврат тех элементов последовательности, для которых функция(элемент) является истинным. Если функция нет, возвращать вещи, которые являются истинными. Если последовательность представляет собой кортеж или String, возвращают тот же тип, в противном случае возвращается список.

Комментарии (0)

Здесь's некоторые возможные пути достижения этой задачи:

def attempt1(string):
    return "".join([v for v in string if v not in ("a", "e", "i", "o", "u")])

def attempt2(string):
    for v in ("a", "e", "i", "o", "u"):
        string = string.replace(v, "")
    return string

def attempt3(string):
    import re
    for v in ("a", "e", "i", "o", "u"):
        string = re.sub(v, "", string)
    return string

def attempt4(string):
    return string.replace("a", "").replace("e", "").replace("i", "").replace("o", "").replace("u", "")

for attempt in [attempt1, attempt2, attempt3, attempt4]:
    print(attempt("murcielago"))

ЗЫ: вместо того, чтобы использовать и" ?.!/;:" в этих примерах гласные... и да, на "карьер" это испанское слово сказать летучая мышь... смешное слово, так как он содержит все гласные :)

ПС2: если вы'повторно заинтересованы в производительности вы могли бы измерить эти попытки с помощью простого кода:

import timeit

K = 1000000
for i in range(1,5):
    t = timeit.Timer(
        f"attempt{i}('murcielago')",
        setup=f"from __main__ import attempt{i}"
    ).repeat(1, K)
    print(f"attempt{i}",min(t))

В моей коробке вы'd получите:

attempt1 2.2334518376057244
attempt2 1.8806643818474513
attempt3 7.214925774955572
attempt4 1.7271184513757465

Так что, похоже attempt4 является самым быстрым для данного ввода.

Комментарии (4)

Здесь's мой питон 2/3 совместимую версию. Поскольку перевод API изменилось.

def remove(str_, chars):
    """Removes each char in `chars` from `str_`.

    Args:
        str_: String to remove characters from
        chars: String of to-be removed characters

    Returns:
        A copy of str_ with `chars` removed

    Example:
            remove("What?!?: darn;", " ?.!:;") => 'Whatdarn'
    """
    try:
        # Python2.x
        return str_.translate(None, chars)
    except TypeError:
        # Python 3.x
        table = {ord(char): None for char in chars}
        return str_.translate(table)
Комментарии (3)

Как насчет этого:

def text_cleanup(text):
    new = ""
    for i in text:
        if i not in " ?.!/;:":
            new += i
    return new
Комментарии (2)

Вы также можете использовать функцию для того, чтобы заменить другой вид регулярного выражения или другие модели с использованием списка. С этим, вы можете смешанный регулярное выражение, классовый характер, и очень простой текстовый шаблон. Это's действительно полезно, когда вам нужно заменить много элементов, как HTML и близких.

*Примечание: работает с Python 3.х

import re  # Regular expression library

def string_cleanup(x, notwanted):
    for item in notwanted:
        x = re.sub(item, '', x)
    return x

line = "My example: <strong>A text %very% $clean!!</strong>"
print("Uncleaned: ", line)

# Get rid of html elements
html_elements = ["", "", "<strong>", "</strong>"]
line = string_cleanup(line, html_elements)
print("1st clean: ", line)

# Get rid of special characters
special_chars = ["[!@#$]", "%"]
line = string_cleanup(line, special_chars)
print("2nd clean: ", line)

В string_cleanup функция принимает строку X и свой список notwanted в качестве аргументов. Для каждого элемента в списке элементов, или узор, если нужно заменить, это будет сделано.

Вывод:

Uncleaned:  My example: <strong>A text %very% $clean!!</strong>
1st clean:  My example: A text %very% $clean!!
2nd clean:  My example: A text very clean
Комментарии (0)

Мой способ я'd с помощью, наверное, не'т работать так же эффективно, но это очень просто. Я могу удалить несколько символов в разных позициях одновременно, используя нарезания и форматирования. Здесь'ы пример:

words = "things"
removed = "%s%s" % (words[:3], words[-1:])

Это приведет к 'удалено' держать слово 'Это'.

Форматирование может быть очень полезно для печати переменных на полпути через строку печать. В него можно вставить любой тип данных с помощью %, после чего переменная's данные Тип; все типы данных можно использовать , а плавает (ака десятичные числа) и целые числа, можно использовать .

Нарезки могут быть использованы для четкого управления строками. Когда я положил слова[:3], это позволяет мне выбрать все символы в строке от начала (двоеточие перед номером, это будет означать, что 'С самого начала') в 4-й персонаж (он включает в себя 4-й персонаж). Причина 3 составляет до 4-й позиции, потому что Python начинается с 0. Потом, когда я положил слово[-1:], это означает, 2-ой последний символ (двоеточие после номера). Поставив -1 будет рассчитывать на Python от последнего символа, а не первый. Опять же, питон начнется в 0. Так, слово[-1:] в основном означает, что 'из Второго последнего символа до конца строки.

Так, путем отсечения символов перед знаком, я хочу удалить и символы после и прослаивая их вместе, я могу удалить нежелательный характер. Думайте о нем, как колбаса. В середине он'ы грязные, поэтому я хочу избавиться от него. Я просто отрезают два конца я хочу, чтобы потом сложить их вместе без нежелательных часть в середине.

Если я хочу удалить несколько символов подряд, я просто сместить цифры в [] (отрезать часть). Или если я хочу удалить несколько персонажей с разных позиций, я могу просто бутерброд несколько ломтиков сразу.

Примеры:

 words = "control"
 removed = "%s%s" % (words[:2], words[-2:])

удалено равна 'круто'.

words = "impacts"
removed = "%s%s%s" % (words[1], words[3:5], words[-1])

удалено равна 'маки'.

В этом случае, [3:5] означает символ в установки 3 через символ в установки 5 (за исключением символа в конечной позиции).

Помните, Python начинается отсчет с 0, так что вам будет нужно так же.

Комментарии (0)
#!/usr/bin/python
import re

strs = "how^ much for{} the maple syrup? $20.99? That's[] ricidulous!!!"
print strs
nstr = re.sub(r'[?|$|.|!|a|b]',r' ',strs)#i have taken special character to remove but any #character can be added here
print nstr
nestr = re.sub(r'[^a-zA-Z0-9 ]',r'',nstr)#for removing special character
print nestr
Комментарии (2)

Метод строку "заменить" не изменяет исходную строку. Он оставит в покое и возвращает измененную копию.

Что вы хотите, что-то вроде: линия=.заменить(Чара,&#39;&#39;)

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

Однако, создавая новую строку каждый раз, что персонаж удален, очень неэффективно. Вместо этого я рекомендую следующее:

def replace_all(line, baddies, *):
    """
    The following is documentation on how to use the class,
    without reference to the implementation details:

    For implementation notes, please see comments begining with `#`
    in the source file.

    [*crickets chirp*]

    """

    is_bad = lambda ch, baddies=baddies: return ch in baddies
    filter_baddies = lambda ch, *, is_bad=is_bad: "" if is_bad(ch) else ch
    mahp = replace_all.map(filter_baddies, line)
    return replace_all.join('', join(mahp))

    # -------------------------------------------------
    # WHY `baddies=baddies`?!?
    #     `is_bad=is_bad`
    # -------------------------------------------------
    # Default arguments to a lambda function are evaluated
    # at the same time as when a lambda function is
    # **defined**.
    #
    # global variables of a lambda function
    # are evaluated when the lambda function is
    # **called**
    #
    # The following prints "as yellow as snow"
    #
    #     fleece_color = "white"
    #     little_lamb = lambda end: return "as " + fleece_color + end
    #
    #     # sometime later...
    #
    #     fleece_color = "yellow"
    #     print(little_lamb(" as snow"))
    # --------------------------------------------------
replace_all.map = map
replace_all.join = str.join
Комментарии (0)

Попробуйте это:

def rm_char(original_str, need2rm):
    ''' Remove charecters in "need2rm" from "original_str" '''
    return original_str.translate(str.maketrans('','',need2rm))

Этот метод хорошо работает в Python 3.5.2

Комментарии (0)
>>> # Character stripping
>>> a = '?abcd1234!!'
>>> t.lstrip('?')
'abcd1234!!'
>>> t.strip('?!')
'abcd1234'
Комментарии (1)