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

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

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

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

Ответ 1

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

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

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

line = line.translate(None, '[email protected]#$')

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

import re
line = re.sub('[[email protected]#$]', '', line)

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

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

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

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

translation_table = dict.fromkeys(map(ord, '[email protected]#$'), 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 '[email protected]#$'})

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

import string
line = line.translate(string.maketrans('', ''), '[email protected]#$')

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

Ответ 2

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

string = "ab1cd1ef"
string.replace("1","") 

print string
# result: "abcdef"

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

a = "[email protected]#d$"
b = "[email protected]#$"
for char in b:
    a = a.replace(char,"")

print a
# result: "abcd"

Ответ 3

>>> line = "abc#@!?efg12;:?"
>>> ''.join( c for c in line if  c not in '?:!/;' )
'abc#@efg12'

Ответ 4

Легко peasy с регулярным выражением re.sub в Python 3.5

re.sub('\ |\?|\.|\!|\/|\;|\:', '', line)
Пример

Example

>>> import re

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

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

Объяснение

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

Ответ 5

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

Ответ 6

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

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

Вам не нужно делать вложенные элементы if/for, но вам нужно проверить каждый символ отдельно.

Ответ 7

line = line.translate(None, " ?.!/;:")

Ответ 8

>>> s = 'a1b2c3'
>>> ''.join(c for c in s if c not in '123')
'abc'

Ответ 9

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

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

Ответ 10

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

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

    s = "1212edjaq"

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

    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"

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

UPDATE

Логично, что поскольку фильтр работает, вы также можете использовать понимание списков, и из того, что я прочитал, он должен быть более эффективным, потому что лямбды являются менеджерами хедж-фондов Уолл-стрит в мире функций программирования. Еще одним плюсом является то, что это однострочник, который не требует импорта. Например, используя ту же строку '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])

Ответ 11

Используя filter, вам понадобится всего одна строка

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

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

>>> help(filter)
Help on built-in function filter in module __builtin__:

filter(...)
    filter(function or None, sequence) -> list, tuple, or string

    Return those items of sequence for which function(item) is true.  If
    function is None, return the items that are true.  If sequence is a tuple
    or string, return the same type, else return a list.

Ответ 12

Вот несколько возможных способов достижения этой задачи:

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

PS: Вместо использования "?.!/;:" в примерах используются гласные... и да, "murcielago" - это испанское слово сказать bat... смешное слово, поскольку оно содержит все гласные :)

PS2: Если вы заинтересованы в производительности, вы можете измерить эти попытки с помощью простого кода:

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

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

attempt1 2.2334518376057244
attempt2 1.8806643818474513
attempt3 7.214925774955572
attempt4 1.7271184513757465

Таким образом, кажется, что try4 является самым быстрым для этого конкретного входа.

Ответ 13

Здесь моя совместимая с Python 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)

Ответ 14

Вы должны переназначить свою переменную str:

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

Ответ 15

>>> # Character stripping
>>> a = '?abcd1234!!'
>>> t.lstrip('?')
'abcd1234!!'
>>> t.strip('?!')
'abcd1234'

Ответ 16

#!/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

Ответ 17

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

def text_cleanup(text):
    new = ""
    for i in text:
        if i not in " ?.!/;:":
            new += i
    return new

Ответ 18

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

* NB: работает с Python 3.x

import re  # Regular expression library


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

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

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

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

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

Выход:

Uncleaned:  <title>My example: <strong>A text %very% $clean!!</strong></title>
1st clean:  My example: A text %very% $clean!!
2nd clean:  My example: A text very clean

Ответ 19

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

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

Это приведет к "удалению", содержащему слово 'this'.

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

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

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

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

Примеры:

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

удалено равно 'cool'.

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

удалено равно "macs".

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

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

Ответ 20

Ниже... без использования концепции регулярного выражения.

ipstring ="text with [email protected]#$^&*( ends here"
opstring=''
for i in ipstring:
    if i.isalnum()==1 or i==' ':
        opstring+=i
    pass
print opstring

Ответ 21

В Python 3.5

например.

os.rename(file_name, file_name.translate({ord(c): None for c in '0123456789'}))

Чтобы удалить все число из строки

Ответ 22

Даже приведенный ниже подход работает

line = "a,b,c,d,e"
alpha = list(line)
        while ',' in alpha:
            alpha.remove(',')
finalString = ''.join(alpha)
print(finalString)

вывод: abcde

Ответ 23

вы можете использовать set

    charlist = list(set(string.digits+string.ascii_uppercase) - set('10IO'))
    return ''.join([random.SystemRandom().choice(charlist) for _ in range(passlen)])

Ответ 24

Попробуйте следующее:

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

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

Ответ 25

Рекурсивное разделение: s = строка; chars = символы для удаления

def strip(s,chars):
if len(s)==1:
    return "" if s in chars else s
return strip(s[0:int(len(s)/2)],chars) +  strip(s[int(len(s)/2):len(s)],chars)

пример:

print(strip("Hello!","lo"))    #He!

Ответ 26

Это самый пифонический образ, который, я думаю, может быть.

clean_string = ''.join(dirty_string.strip(char_you_want_to_remove))

Ответ 27

Вы можете использовать замену регулярного выражения re модуля. Использование выражения ^ позволяет вам выбрать именно то, что вы хотите от вашей строки.

    import re
    text = "This is absurd!"
    text = re.sub("[^a-zA-Z]","",text) # Keeps only Alphabets
    print(text)

Выходом к этому будет "Thisisabsurd". Появятся только те вещи, которые указаны после символа ^.

Ответ 28

# для каждого файла в каталоге переименовать имя файла

   file_list = os.listdir (r"D:\Dev\Python")

   for file_name in file_list:

       os.rename(file_name, re.sub(r'\d+','',file_name))