Как заменить / изменить шаблон с помощью регулярного выражения в Python? - PullRequest
4 голосов
/ 26 июня 2019

Предположим, что я хочу изменить все шаблоны в сценарии, возьмем одну строку в качестве примера:

line = "assert Solution().oddEvenList(genNode([2,1,3,5,6,4,7])) == genNode([2,3,6,7,1,5,4]), 'Example 2'"

Обратите внимание, что функция genNode принимает List[int] в качестве параметра. Я хочу удалить список и сохранить все целые числа в списке, чтобы функция фактически принимала *nums в качестве параметров.

Ожидать:

line = "assert Solution().oddEvenList(genNode(2,1,3,5,6,4,7)) == genNode(2,3,6,7,1,5,4), 'Example 2'"

Я придумал шаблон re

r"([g][e][n][N][o][d][e][(])([[][0-9\,\s]*[]])([)])"

но я не уверен, как я мог бы использовать это ... Я не могу заставить re.sub работать, потому что это требует, чтобы я заменил на фиксированную строку.

Как мне достичь желаемого результата?

Ответы [ 2 ]

1 голос
/ 26 июня 2019

Вместо записи [g][e][n][N][o][d][e][(] вы можете написать getNode\(

Текущий класс символов, который вы используете [0-9\,\s]*, соответствует 0+ раз любому из перечисленных, которые также могут, например, соответствовать только запятым, и не гарантирует наличие разделенных запятыми цифр.

Чтобы соответствовать целым числам запятого, вы можете сопоставить цифры 1+ с повторяющейся группой, чтобы они соответствовали запятой и цифрам 1+.

В конце используйте положительный прогноз, чтобы подтвердить закрывающую скобку или захватите ее в группе 3, а также используйте это при замене.

С этим шаблоном используйте r'\1\2 в качестве замены.

(genNode\()\[(\d+(?:,\d+)*)\](?=\))

Объяснение

  • (genNode\() Захват в группе 1, соответствующий genNode(
  • \[ Совпадение [
  • ( Захватывающая группа 2
    • \d+(?:,\d+)* Совпадение 1+ цифр и повторение 0+ раз запятой и 1+ цифр (для поддержки одной цифры)
  • ) Закрыть группу 2
  • \] Совпадение ]
  • (?=\)) Положительный взгляд, утверждаем, что справа - закрывающая скобка )

Python demo | Regex demo

Например

import re

regex = r"(genNode\()\[(\d+(?:,\d+)*)\](?=\))"
line = "assert Solution().oddEvenList(genNode([2,1,3,5,6,4,7])) == genNode([2,3,6,7,1,5,4]), 'Example 2'"
result = re.sub(regex, r"\1\2", line)

if result:
    print (result)

Результат

assert Solution().oddEvenList(genNode(2,1,3,5,6,4,7)) == genNode(2,3,6,7,1,5,4), 'Example 2'
1 голос
/ 26 июня 2019

Вы можете сделать:

re.sub(r'(genNode\()\[([^]]+)\]', r'\1\2', line)
  • (genNode\() совпадений genNode( и поместить его в захваченную группу 1
  • \[ совпадений буквально [
  • ([^]]+) соответствует следующему ] и помещает его в захваченную группу 2
  • \] соответствует буквальному ]

В замене мы имеемиспользовали только захваченные группы, то есть отброшенные [ и ].


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

re.sub(r'(?<=genNode\()\[([^]]+)\]', r'\1', line)

Пример:

In [444]: line = "assert Solution().oddEvenList(genNode([2,1,3,5,6,4,7])) == genNode([2,3,6,7,1,5,4]), 'Example 2'"                                                                                         

In [445]: re.sub(r'(genNode\()\[([^]]+)\]', r'\1\2', line)                                                                                                                                                  
Out[445]: "assert Solution().oddEvenList(genNode(2,1,3,5,6,4,7)) == genNode(2,3,6,7,1,5,4), 'Example 2'"

In [446]: re.sub(r'(?<=genNode\()\[([^]]+)\]', r'\1', line)                                                                                                                                                 
Out[446]: "assert Solution().oddEvenList(genNode(2,1,3,5,6,4,7)) == genNode(2,3,6,7,1,5,4), 'Example 2'"

FWIW, используя вместо этого типичный не жадный шаблон .*?из [^]]+ также будет работать:

re.sub(r'(?<=genNode\()\[(.*?)\]', r'\1', line)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...