Python: замена нескольких указанных c слов из списка на re.sub - PullRequest
3 голосов
/ 03 марта 2020

У меня есть следующая строка и список «changewords». Я хотел бы заменить '{слово из списка} \ n' на '{слово из списка}:' Я не хочу заменять все экземпляры '\ n'.

string = "Foo \n value of something \n Bar \n Another value \n"
changewords = ["Foo", "Bar"]

Требуемый вывод:

'Foo: value of something \n Bar: Another value \n'

Я пробовал следующие

for i in changewords:
    tem = re.sub(f'{i} \n', f'{i}:', string)
tem
Output: 'Foo \n value of something \n Bar: Another value \n'

и

changewords2 = '|'.join(changewords)
tem = re.sub(f'{changewords2} \n', f'{changewords2}:', string)
tem
Output: 'Foo|Bar: \n value of something \n Foo|Bar: Another value \n'

Как мне получить мой желаемый вывод?

Ответы [ 3 ]

2 голосов
/ 03 марта 2020

Вы можете использовать этот код:

import re

string = "Foo \n value of something \n Bar \n Another value \n"
changewords = ["foo", "Bar"]

tem = string
for i in changewords:
    tem = re.sub(f'(?i){i} \n', f'{i}:', tem)
print( tem )

Выход:

foo: value of something
 Bar: Another value

Примечание tem = string для инициализации значения tem и затем внутри for l oop использовать re.sub для tem с присвоением обратного результата самому tem.

Использование (?i) для игнорирования сопоставления регистра.

Код Демо

1 голос
/ 03 марта 2020

Использование замещающей строки:

Несколько более элегантный способ сделать это. Этот однострочный:

re.sub(rf"({'|'.join(changewords)}) \n", r"\1:", string, flags=re.I)

demo:

>>> string = "Foo \n value of something \n Bar \n Another value \n"
>>> changewords = ['Foo', 'Bar', 'Baz', 'qux']
>>> 
>>> re.sub(rf"({'|'.join(changewords)}) \n", r"\1:", string, flags=re.I)
'Foo: value of something \n Bar: Another value \n'
>>> 

Вы можете указать регистрозависимое соответствие с опцией flags. И заменяющую строку можно изменить так, чтобы в ней было что-то около \1, например, двоеточия или запятые.

Стоит отметить, что вы можете указать более одного спецификатора для строк в Python. Например, вы можете иметь как r, так и f, например, rf"my raw formatted string" - порядок спецификаторов не важен.

Внутри выражения в re.sub(expr, repl, string) вы можете указывать группы. Группы создаются путем помещения круглых скобок () вокруг текста.

Группы можно ссылаться в строке замены repl, используя обратную косую черту sh и номер ее появления - первая группа упомянутый \1.

Функция re.sub(), re.sub(rf"(A|B|C) \n", r"\1: "), связывает \1 в строке замены с первой группой (A|B|C) в аргументе выражения.

Использование функции замены:

Предположим, вы хотите заменить слова в целевой строке другими словами из словаря. Например, вы хотите, чтобы 'Bar' был заменен на 'Hank', а 'Foo' на 'Bernard'. Это можно сделать с помощью функции замены вместо строки замены:

>>> repl_dict = {'Foo':'Bernard', 'Bar':'Hank'}
>>> 
>>> expr = rf"({'|'.join(repl_dict.keys())}) \n"   # Becomes '(Foo|Bar) \\n'
>>>
>>> func = lambda mo: f"{repl_dict[mo.group(1)]}:"
>>> 
>>> re.sub(expr, func, string, flags=re.I)
'Bernard: value of something \n Hank: Another value \n'
>>> 

Это может быть еще одна строка, но я разбил ее для ясности ...

Что за лямбда-функция делает, берет объект соответствия, mo передается ему, затем извлекает текст первой группы. Первая группа в выражении reg - это текст, заключенный в (), который будет выглядеть как (A|B|C).

Функция замены ссылается на эту первую группу, используя mo.group(1); аналогично, строка замены ссылается на нее, \1 в предыдущем примере.

Затем функция repl выполняет поиск в dict и возвращает окончательную строку замены для совпадения.

0 голосов
/ 03 марта 2020

Вы вполне могли бы вообще не использовать регулярные выражения, и мой первый подход - использовать встроенную строковую функцию .replace(), чтобы она выглядела примерно так:

string = "Foo \n value of something \n Bar \n Another value \n"
changewords = ["Foo", "Bar"]

for word in changewords:
   to_replace = "{0} \n".format(word)
   replacement = "{0}:".format(word)
   string = string.replace(to_replace, replacement)

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...