Мне нужно заменить некоторые символы следующим образом: &\&, #\#, ...

Я кодировал следующим образом, но я думаю, что должен быть какой-то лучший способ. Есть намеки?

strs = strs.replace('&', '\&')
strs = strs.replace('#', '\#')
...
303
prosseek 5 Авг 2010 в 08:34

10 ответов

К вашему сведению, это мало что значит для ОП, но может быть полезным для других читателей (пожалуйста, не понижайте голос, я знаю об этом).

Как нелепое, но интересное упражнение, я хотел посмотреть, смогу ли я использовать функциональное программирование на Python для замены нескольких символов. Я почти уверен, что это НЕ побеждает, просто вызывая replace () дважды. И если производительность была проблемой, вы могли бы легко победить это в ржавчине, C, Julia, Perl, Java, Javascript и, возможно, даже awk. Он использует внешний пакет «помощников» под названием pytoolz, ускоренный с помощью Cython (cytoolz, это пакет pypi).

from cytoolz.functoolz import compose
from cytoolz.itertoolz import chain,sliding_window
from itertools import starmap,imap,ifilter
from operator import itemgetter,contains
text='&hello#hi&yo&'
char_index_iter=compose(partial(imap, itemgetter(0)), partial(ifilter, compose(partial(contains, '#&'), itemgetter(1))), enumerate)
print '\\'.join(imap(text.__getitem__, starmap(slice, sliding_window(2, chain((0,), char_index_iter(text), (len(text),))))))

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

3
parity3 29 Янв 2016 в 22:53

Вы всегда собираетесь добавить обратную косую черту? Если так, попробуйте

import re
rx = re.compile('([&#])')
#                  ^^ fill in the characters here.
strs = rx.sub('\\\\\\1', strs)

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

15
kennytm 5 Авг 2010 в 04:39

Вот метод python3 с использованием str.translate и < a href = "https://docs.python.org/3/library/stdtypes.html#str.maketrans" rel = "noreferrer"> str.maketrans :

s = "abc&def#ghi"
print(s.translate(str.maketrans({'&': '\&', '#': '\#'})))

Напечатанная строка: abc\&def\#ghi.

22
tommy.carstensen 10 Фев 2018 в 02:59
>>> string="abc&def#ghi"
>>> for ch in ['&','#']:
...   if ch in string:
...      string=string.replace(ch,"\\"+ch)
...
>>> print string
abc\&def\#ghi
72
ghostdog74 5 Авг 2010 в 05:54

Вы можете написать общую функцию escape:

def mk_esc(esc_chars):
    return lambda s: ''.join(['\\' + c if c in esc_chars else c for c in s])

>>> esc = mk_esc('&#')
>>> print esc('Learn & be #1')
Learn \& be \#1

Таким образом, вы можете сделать свою функцию настраиваемой со списком символов, которые должны быть экранированы.

6
Victor Olex 16 Фев 2011 в 05:17

Опоздал на вечеринку, но я потерял много времени на эту проблему, пока не нашел свой ответ.

Коротко и сладко, translate превосходит replace . Если вас больше интересует функциональность с течением времени, не используйте replace.

Также используйте translate, если вы не знаете, перекрывает ли набор символов, подлежащих замене, набор символов, используемых для замены.

Дело в точке:

Используя replace, вы наивно ожидаете, что фрагмент "1234".replace("1", "2").replace("2", "3").replace("3", "4") вернет "2344", но фактически он вернет "4444".

Похоже, что перевод выполняет то, что изначально требовалось.

7
Sebastialonso 29 Мар 2019 в 23:36

Используя Reduction, который доступен в python2.7 и python3. *, Вы можете легко заменить несколько подстрок чистым и питонным способом.

# Lets define a helper method to make it easy to use
def replacer(text, replacements):
    return reduce(
        lambda text, ptuple: text.replace(ptuple[0], ptuple[1]), 
        replacements, text
    )

if __name__ == '__main__':
    uncleaned_str = "abc&def#ghi"
    cleaned_str = replacer(uncleaned_str, [("&","\&"),("#","\#")])
    print(cleaned_str) # "abc\&def\#ghi"

В python2.7 вам не нужно импортировать Reduce, но в Python3. * Вы должны импортировать его из модуля functools.

1
CasualCoder3 29 Янв 2018 в 12:08

Просто цепочка функций replace, как это

strs = "abc&def#ghi"
print strs.replace('&', '\&').replace('#', '\#')
# abc\&def\#ghi

Если замен будет больше, вы можете сделать это в общем виде

strs, replacements = "abc&def#ghi", {"&": "\&", "#": "\#"}
print "".join([replacements.get(c, c) for c in strs])
# abc\&def\#ghi
32
thefourtheye 9 Май 2014 в 11:46

Может быть, простой цикл для замены символов:

a = '&#'

to_replace = ['&', '#']

for char in to_replace:
    a = a.replace(char, "\\"+char)

print(a)

>>> \&\#
1
Tiago Wutzke de Oliveira 25 Фев 2020 в 14:25
>>> a = '&#'
>>> print a.replace('&', r'\&')
\&#
>>> print a.replace('#', r'\#')
&\#
>>> 

Вы хотите использовать «сырую» строку (обозначаемую как «r» префиксом замещающей строки), поскольку необработанные строки не обрабатывают обратную косую черту специально.

0
jonesy 16 Фев 2011 в 03:22