Поиск и замена текста с помощью регулярных выражений Python
Просьба строго не судить: чтобы изучить питон поставил задачу пока работать с текстом.
Суть задачи: Записать значения из последнего списка на те же места где они и стояли
Ищу отрывок текста в строке text="...." с помощью RegEx, получаю в виде списка друг за другом [Build Cravan, Caravan Menu, Leave]
Перевожу эти значения на язык который мне надо
Потом перевожу их обратно в список допустим [Создать Караван, Меню Каравана, Покинуть]
Как записать значения из второго списка также как они стояли по порядку в текст по шаблону?
Ответы (2 шт):
Можно использовать re.sub() с указанием функции как аргумента для замены захваченных фрагментов:
import re
xml = '''<?xml version="1.0" encoding="utf-8"?>
<base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" type="string
<tags>
<tag language="English"/>
</tags>
<strings>
<string id="caravan_build" text="Build Caravan"/>
<string id="caravan_menu" text="Caravan Menu"/>
<string id="caravan_menu_leave" text="Leave"/>
</strings>
</base>'''
def translate_words(words): # здесь переводите захваченный текст
return words[0][::-1] # для примера - реверс текста
xml1 = re.sub(r'(?<=text=").*(?=")', translate_words, xml)
print(xml1)
<?xml version="1.0" encoding="utf-8"?>
<base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" type="string
<tags>
<tag language="English"/>
</tags>
<strings>
<string id="caravan_build" text="navaraC dliuB"/>
<string id="caravan_menu" text="uneM navaraC"/>
<string id="caravan_menu_leave" text="evaeL"/>
</strings>
</base>
Другой (и, наверное, более правильный способ) - распарсить XML и заменить значения атрибутов:
import xml.etree.ElementTree as ET
xml = '''<?xml version="1.0" encoding="utf-8"?>
<base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" type="string">
<tags>
<tag language="English"/>
</tags>
<strings>
<string id="caravan_build" text="Build Caravan"/>
<string id="caravan_menu" text="Caravan Menu"/>
<string id="caravan_menu_leave" text="Leave"/>
</strings>
</base>'''
tree = ET.fromstring(xml)
all_name_elements = tree.findall('.//string')
for element in all_name_elements:
txt = element.get('text')
element.set('text', txt[::-1])
ET.dump(tree)
<base type="string">
<tags>
<tag language="English" />
</tags>
<strings>
<string id="caravan_build" text="navaraC dliuB" />
<string id="caravan_menu" text="uneM navaraC" />
<string id="caravan_menu_leave" text="evaeL" />
</strings>
</base>
Крайне не рекомндуется работать с XML как с текстом, используйте библиотеки, рекомендую установить lxml. Вот код, там приведен пример корректного XML, который ответ от Алексей Р обработает неверно, там есть атрибут context, атрибут text может встретиься в любом другом элементе, ну а фрагмент CDATA (редко встречающийся) может вообще содержать внутри любой текст.
import lxml.etree as ET
xml = b'''<?xml version="1.0" encoding="utf-8"?>
<base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" type="string">
<tags>
<tag language="English"/>
</tags>
<strings>
<![CDATA[
text="Build Caravan"
]]>
<string id="caravan_build" text="Build Caravan"/>
<string id="caravan_menu" context="Caravan Menu"/>
<string id="caravan_menu_leave" text="Leave"/>
</strings>
</base>'''
def translate_words(words): # здесь переводите захваченный текст
return words[::-1] # для примера - реверс текста
xml0 = ET.fromstring(xml)
for t in xml0.findall('./strings/string[@text]'):
t.set('text', translate_words(t.get('text')))
print(ET.tostring(xml0, xml_declaration=True, encoding='utf8').decode('utf8'))
P.S. Вероятно, у Вас работа с файлами, там прямо из файла и в файл есть функции.
P.P.S. Чтобы не путать с соответствием переводимых фраз удобно именно для каждого перевода вызывать функцию
