Удаление определенных символов из строки в 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))