Замена повторных захватов

Это своего рода продолжение к регулярному выражению Python. Замените одиночные кавычки и скобки .

Задание:

Примеры входных строк:

RSQ(name['BAKD DK'], name['A DKJ']) SMT(name['BAKD DK'], name['A DKJ'], name['S QRT']) 

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

 XYZ(BAKD DK, A DKJ) XYZ(BAKD DK, A DKJ, S QRT) 

Количество name['something'] -подобных элементов является переменной .

Текущее решение:

В настоящее время я делаю это через два отдельных re.sub() :

 >>> import re >>> >>> s = "RSQ(name['BAKD DK'], name['A DKJ'])" >>> s1 = re.sub(r"^(\w+)", "XYZ", s) >>> re.sub(r"name\['(.*?)'\]", r"\1", s1) 'XYZ(BAKD DK, A DKJ)' 

Вопрос:

Можно ли объединить эти два re.sub() в один?

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


Я заглянул в модуль regex – это способность захватывать повторяющиеся шаблоны выглядит очень многообещающе, и попытался использовать regex.subf() но не смог заставить его работать.

4 Solutions collect form web for “Замена повторных захватов”

Вы действительно можете использовать модуль регулярных выражений и повторные захваты. Основной интерес состоит в том, что вы можете проверить структуру согласованной строки:

 import regex regO = regex.compile(r''' \w+ \( (?: name\['([^']*)'] (?: ,[ ] | (?=\)) ) )* \) ''', regex.VERBOSE); regO.sub(lambda m: 'XYZ(' + (', '.join(m.captures(1))) + ')', s) 

(Обратите внимание, что вы можете заменить "name" на \w+ или все, что хотите, без проблем.)

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

Вы пытаетесь разобрать синтаксически корректный Python. Для этого используйте ast . Это более читаемо, проще распространяться на новый синтаксис и не разваливаться на какой-то странный угловой случай.

Рабочий образец:

 from ast import parse l = [ "RSQ(name['BAKD DK'], name['A DKJ'])", "SMT(name['BAKD DK'], name['A DKJ'], name['S QRT'])" ] for item in l: tree = parse(item) args = [arg.slice.value.s for arg in tree.body[0].value.args] output = "XYZ({})".format(", ".join(args)) print(output) 

Печать:

 XYZ(BAKD DK, A DKJ) XYZ(BAKD DK, A DKJ, S QRT) 

Вы могли бы это сделать. Хотя я не думаю, что это очень читаемо. И сделать это таким образом может стать непоколебимым, если вы начнете добавлять больше шаблонов для замены. Он использует тот факт, что строка замены также может быть функцией.

 s = "RSQ(name['BAKD DK'], name['A DKJ'])" re.sub(r"^(\w+)|name\['(.*?)'\]", lambda m: 'XYZ' if m.group(1) else m.group(2), s) 

Вы можете использовать re.findall() и простое форматирование строки:

 >>> s = "SMT(name['BAKD DK'], name['A DKJ'], name['S QRT'])" >>> >>> 'XYZ({})'.format(','.join(re.findall(r"'([^']+)'", s))) 'XYZ(BAKD DK,A DKJ,S QRT)' 
  • Число фильтров Regex делится на 3
  • Python Regex - заменить строку, не расположенную между двумя конкретными словами
  • регулярное выражение python "\ 1"
  • как сделать re.compile () со списком в python
  • Соответствие регулярного выражения Python в условных выражениях
  • Regex Apostrophe как совместить?
  • Не работаю для меня
  • Python RE (слово для проверки первой буквы чувствительно к регистру и остальное нечувствительно к регистру)
  • Python - лучший язык программирования в мире.