Я'пытаюсь удалить определенные символы из строки с помощью Python. Вот код, который я использую сейчас. К сожалению, он ничего не делает со строкой.
for char in line:
if char in " ?.!/;:":
line.replace(char,'')
Как мне правильно это сделать?
Строки в 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.
Я что-то недопонимаете, или это просто следующее:
``питон строка = "и ab1cd1ef и" строку.заменить (на"1" и" Ну и")
строки для печати
``
Положить его в цикле:
``puthon а = "а!б@с#д&Я$; Б = и"!@#$&и" для гольца в б: а = а.заменить(Чара, и" и")
распечатать
``
>>> line = "abc#@!?efg12;:?"
>>> ''.join( c for c in line if c not in '?:!/;' )
'abc#@efg12'
re.sub('\ |\?|\.|\!|\/|\;|\:', '', line)
Пример ###
>>> import re
>>> line = 'Q: Do I write ;/.??? No!!!'
>>> re.sub('\ |\?|\.|\!|\/|\;|\:', '', line)
'QDoIwriteNo'
В регулярные выражения (регулярные выражения), |
- это логическое ИЛИ и избегает пробелов и специальных символов, которые могут быть команды регулярного выражения. В то время как суб
расшифровывается замена в этом случае с пустой строкой''
.
Для обратной требование только позволяет некоторые символы в строке, вы можете использовать регулярные выражения с оператором дополнением [^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', и[ ^ ^ ] соответствует любому символу, за исключением
'^'.
^` не имеет особого смысла, если это не первый персонаж набор.
Автор вопроса почти получилось. Как и большинство вещей в Python, ответ проще, чем вы думаете.
>>> line = "H E?.LL!/;O:: "
>>> for char in ' ?.!/;:':
... line = line.replace(char,'')
...
>>> print line
HELLO
Вы Don'т придется делать вложенные if/for цикл вещь, но вы должны проверить каждый символ в отдельности.
line = line.translate(None, " ?.!/;:")
Строки в Python неизменяемы. Метод replace
возвращает новую строку после замены. Попробуйте:
for char in line:
if char in " ?.!/;:":
line = line.replace(char,'')
Я был удивлен, что никто еще не рекомендовал использовать встроенный <б>фильтр</б> функция.
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 это возвращается
>> <filter object @ hex>
Чтобы получить печатную строку,
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])
Используя фильтр
, Вы'd только одна строка
line = filter(lambda char: char not in " ?.!/;:", line)
Это относится к строке, как и проверяет, повторяемое каждый персонаж при лямбда
возвращает true
:
помощь(фильтр) помощь на встроенную функцию фильтра в модуле строение:
фильтр(...) фильтр(функция или нет, последовательность) -> Список, кортеж, строка
возврат тех элементов последовательности, для которых функция(элемент) является истинным. Если функция нет, возвращать вещи, которые являются истинными. Если последовательность представляет собой кортеж или String, возвращают тот же тип, в противном случае возвращается список.
Здесь'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 является самым быстрым для данного ввода.
Здесь'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)
Вы также можете использовать функцию для того, чтобы заменить другой вид регулярного выражения или другие модели с использованием списка. С этим, вы можете смешанный регулярное выражение, классовый характер, и очень простой текстовый шаблон. Это'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 = "<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 = ["[!@#$]", "%"]
line = string_cleanup(line, special_chars)
print("2nd clean: ", line)
В string_cleanup функция принимает строку X и свой список notwanted в качестве аргументов. Для каждого элемента в списке элементов, или узор, если нужно заменить, это будет сделано.
Вывод:
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
Мой способ я'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, так что вам будет нужно так же.
#!/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
Метод строку "заменить" не изменяет исходную строку. Он оставит в покое и возвращает измененную копию.
Что вы хотите, что-то вроде: линия=.заменить(Чара,'')
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
Попробуйте это:
def rm_char(original_str, need2rm):
''' Remove charecters in "need2rm" from "original_str" '''
return original_str.translate(str.maketrans('','',need2rm))
Этот метод хорошо работает в Python 3.5.2
>>> # Character stripping
>>> a = '?abcd1234!!'
>>> t.lstrip('?')
'abcd1234!!'
>>> t.strip('?!')
'abcd1234'