Я хотел бы использовать функцию .replace, чтобы заменить несколько строк.
У меня сейчас
string.replace("condition1", "")
но хотелось бы что то типа
string.replace("condition1", "").replace("condition2", "text")
хотя это не похоже на хороший синтаксис
Как правильно это сделать? вроде как в grep / regex вы можете сделать \1
и \2
заменить поля на определенные строки поиска
Ответы:
Вот краткий пример того, что нужно делать с регулярными выражениями:
Например:
источник
"spamham sha".replace("spam", "eggs").replace("sha","md5")
быть"eggmd5m md5"
вместо"eggsham md5"
Вы можете просто сделать хорошую маленькую функцию зацикливания.
где
text
- полная строка иdic
словарь - каждое определение является строкой, которая заменит соответствие термину.Примечание : в Python 3
iteritems()
был заменен наitems()
Осторожно: словари Python не имеют надежного заказа для итерации. Это решение решает вашу проблему, только если:
Например:
Возможный вывод № 1:
Возможный вывод № 2
Одним из возможных исправлений является использование OrderedDict.
Вывод:
Осторожно # 2: неэффективно, если ваша
text
строка слишком большая или в словаре много пар.источник
OrderedDict
- или списка из двух кортежей.Почему бы не одно решение, как это?
источник
Вот вариант первого решения, использующего Reduce, если вам нравится работать. :)
еще лучшая версия Мартино:
источник
repls
последовательность кортежей и покончить сiteritems()
вызовом. т.е.repls = ('hello', 'goodbye'), ('world', 'earth')
иreduce(lambda a, kv: a.replace(*kv), repls, s)
. Также будет работать без изменений в Python 3.reduce
как был удален .reduce
все еще существует, однако он был включен вfunctools
модуль (см. документацию ) в Python 3, поэтому, когда я сказал «без изменений», я имел в виду тот же код, который можно было запустить, хотя, по общему признанию, он потребовалreduce
быimport
редактирования в случае необходимости. так как он больше не является встроенным.Это лишь краткий обзор отличных ответов FJ и MiniQuark. Все, что вам нужно для одновременной замены нескольких строк, это следующая функция:
Использование:
Если вы хотите, вы можете сделать свои собственные специальные функции замены, начиная с этой более простой.
источник
rep_dict = {"but": "mut", "mutton": "lamb"}
строкой это"button"
приводит к"mutton"
вашему коду, но даст,"lamb"
если замены будут связаны, один за другим.Do you prefer cafe? No, I prefer cafe.
, который вовсе не желателен.Я построил это на превосходном ответе FJs:
Использование одного выстрела:
Обратите внимание, что поскольку замена выполняется всего за один проход, «кафе» меняется на «чай», но не возвращается обратно к «кафе».
Если вам нужно много раз выполнять одну и ту же замену, вы можете легко создать функцию замены:
Улучшения:
Наслаждайтесь! :-)
источник
pattern.sub
ожидается функция с одним параметром (текст для замены), поэтому функция должна иметь доступ к нейreplace_dict
.re.M
разрешает многострочные замены (это хорошо объяснено в doc: docs.python.org/2/library/re.html#re.M ).Я хотел бы предложить использовать строковые шаблоны. Просто поместите строку, которую нужно заменить, в словарь, и все готово! Пример из docs.python.org
источник
substitute
возникает исключение, поэтому будьте осторожны при получении шаблонов от пользователей.В моем случае мне потребовалась простая замена уникальных ключей именами, поэтому я подумал:
источник
i
сs
вами бы получить странное поведение.b = [ ['i', 'Z'], ['s', 'Y'] ]; for x,y in (b): a = a.replace(x, y)
тогда, если вы будете осторожны при упорядочении пар массивов, вы можете быть уверены, что не используете replace () рекурсивно.Начав
Python 3.8
и введя выражения присваивания (PEP 572) (:=
оператор), мы можем применить замены в пределах понимания списка:источник
['The quick red fox jumps over the lazy dog', 'The quick red fox jumps over the quick dog']
. Но выражение присваивания (text := text.replace
) также итеративно создает новые версииtext
, изменяя его. После понимания списка вы можете использоватьtext
переменную, которая содержит измененный текст.text
в виде однострочного текста, вы также можете использовать[text := text.replace(a, b) for a, b in replacements][-1]
(обратите внимание на[-1]
), который извлекает последний элемент понимания списка; то есть последняя версияtext
.Здесь мои $ 0,02. Он основан на ответе Эндрю Кларка, немного яснее, и также охватывает случай, когда заменяемая строка является подстрокой другой заменяемой строки (более длинные строки выигрывают)
Именно в этой этой сути , не стесняйтесь изменять его, если у вас есть какие-либо предложения.
источник
Мне нужно было решение, в котором заменяемые строки могут быть регулярными выражениями, например, чтобы помочь нормализовать длинный текст, заменив несколько пробельных символов одним. Основываясь на цепочке ответов от других, включая MiniQuark и mmj, я пришел к такому выводу:
Это работает для примеров, приведенных в других ответах, например:
Для меня главное, что вы также можете использовать регулярные выражения, например, для замены только целых слов или для нормализации пробелов:
Если вы хотите использовать словарные ключи как обычные строки, вы можете избежать их перед вызовом multip_replace, используя, например, эту функцию:
Следующая функция может помочь в нахождении ошибочных регулярных выражений среди ключей вашего словаря (поскольку сообщение об ошибке из множественного_реклама не очень красноречиво):
Обратите внимание, что он не связывает замены, а выполняет их одновременно. Это делает его более эффективным, не ограничивая возможности. Чтобы имитировать эффект цепочки, вам может понадобиться добавить еще пары строк-замен и обеспечить ожидаемое упорядочение пар:
источник
Вот пример, который более эффективен на длинных строках с множеством небольших замен.
Дело в том, чтобы избежать многих конкатенаций длинных строк. Мы разрезаем исходную строку на фрагменты, заменяя некоторые фрагменты при формировании списка, а затем соединяем все это обратно в строку.
источник
Вы действительно не должны делать это таким образом, но я нахожу это слишком крутым:
Теперь
answer
результат всех замен по очередиОпять же, это очень хакерское и не то, что вы должны регулярно использовать. Но просто приятно знать, что вы можете сделать что-то подобное, если вам когда-нибудь понадобится.
источник
Я тоже боролся с этой проблемой. Со многими подстановками регулярные выражения борются и примерно в четыре раза медленнее, чем циклы
string.replace
(в моих условиях эксперимента).Вы должны обязательно попробовать использовать библиотеку Flashtext ( запись в блоге здесь , Github здесь ). В моем случае это было чуть более чем на два порядка быстрее, от 1,8 с до 0,015 с (регулярные выражения занимали 7,7 с) для каждого документа.
Легко найти примеры использования по ссылкам выше, но это рабочий пример:
Обратите внимание, что Flashtext выполняет замены за один проход (чтобы избежать a -> b и b -> c, переводящих «a» в «c»). Flashtext также ищет целые слова (поэтому «is» не будет соответствовать «th is »). Это прекрасно работает, если ваша цель состоит из нескольких слов (замена «Это» на «Привет»).
источник
<p>
на/n
. Я попробовал ваш подход, но с тэгами flashtext, похоже, не разбирает его?<
и>
отметить конец слова (но быть включенным в замену)?Мне кажется, что для полноты этого вопроса нужен однострочный рекурсивный лямбда-ответ. Так что:
Использование:
Ноты:
Примечание: Как и для всех рекурсивных функций в python, слишком большая глубина рекурсии (т. Е. Слишком большие словари замещения) приведет к ошибке. Смотрите, например, здесь .
источник
sys.getrecursionlimit()
это пара 1000, макс. используйте цикл или что-то в этом роде или попробуйте упростить подстановки.Я не знаю о скорости, но это мое быстрое решение:
... но мне нравится ответ № 1 регулярное выражение выше. Примечание: если одно новое значение является подстрокой другого, то операция не является коммутативной.
источник
Вы можете использовать
pandas
библиотеку иreplace
функцию, которая поддерживает как точные совпадения, так и замены регулярных выражений. Например:И измененный текст:
Вы можете найти пример здесь . Обратите внимание, что замены текста выполняются в порядке их появления в списках.
источник
Для замены только одного символа используйте
translate
иstr.maketrans
мой любимый метод.тл; др>
result_string = your_string.translate(str.maketrans(dict_mapping))
демонстрация
источник
Начиная с драгоценного ответа Эндрю, я разработал сценарий, который загружает словарь из файла и разрабатывает все файлы в открытой папке для выполнения замен. Скрипт загружает сопоставления из внешнего файла, в котором вы можете установить разделитель. Я новичок, но я нашел этот скрипт очень полезным при выполнении нескольких замен в нескольких файлах. Он загрузил словарь с более чем 1000 записей в секундах. Это не элегантно, но это сработало для меня
источник
это мое решение проблемы. Я использовал его в чате, чтобы заменить разные слова сразу.
это станет
The cat hunts the dog
источник
Другой пример: список ввода
Желаемый результат будет
Код:
источник
Или просто для быстрого взлома:
источник
Вот еще один способ сделать это с помощью словаря:
источник