Как использовать многострочный DOTALL с исключением символов в Python - PullRequest
3 голосов
/ 21 марта 2019

Мне нужно найти многострочный шаблон в Python.Поэтому я использую DOTALL из регулярных выражений, но он находит больше, чем мне нужно.

образец файла:

if(condition_1)
{
....
some text
some text

if ((condition_1== condition_2)   ||
                 (condition_3== condition_4) ||
           (condition_6== condition_5)  ||
     (condition_7== condition_8)   ) // XYZ_variable
{
...

Мой регулярный выражения Python следует

re.compile(r'(if\s*?\()(.*?)(\/\/\s*?)(XYZ_variable)', re.DOTALL)

этопоиск первого условия if до XYZ_variable, но мне нужно только второе условие if, где присутствует XYZ_variable.

, поэтому я изменил свое регулярное выражение следующим образом, что не работает

re.compile(r'(if\s*?\()([^\{].*?)(\/\/\s*?)(XYZ_variable)', re.DOTALL)

Мой окончательный выводдолжно быть похоже на

if(condition_1)
    {
    ....
    some text
    some text

    if (((condition_1== condition_2)   ||
                     (condition_3== condition_4) ||
               (condition_6== condition_5)  ||
         (condition_7== condition_8)   ) || XYZ_variable )
    {
    ...

но мой регулярное выражение делает что-то вроде этого

if ((condition_1)
        {
        ....
        some text
        some text

        if ((condition_1== condition_2)   ||
                         (condition_3== condition_4) ||
                   (condition_6== condition_5)  ||
             (condition_7== condition_8)   ) || XYZ_variable )
        {
        ...

Ответы [ 2 ]

1 голос
/ 22 марта 2019

Вы можете использовать

re.sub(r'(?m)^(\s*if\s*)(\(.*(?:\n(?!\s*if\s*\().*)*)//\s*(\w+)\s*$', r'\1(\2 || \3)', s)

См. Демоверсию regex .

Подробности

  • (?m) - re.M флаг
  • ^ - начало строки
  • (\s*if\s*) - группа 1: if, заключенная в 0+ пробелов
  • (\(.*(?:\n(?!\s*if\s*\().*)*)- Группа 2:
    • \( - (
    • .* - остаток строки
    • (?:\n(?!\s*if\s*\().*)* - 0 или более повторений
      • \n(?!\s*if\s*\() - новая строка LF, за которой не следует if, заключенная в 0+ пробелов, а затем (
      • .* - остальная часть строки
  • //\s* - // и 0+ пробелов
  • (\w+) - Группа 3: 1 или более слов символов
  • \s*$ - 0+ пробелов и конец строки.

Демонстрация Python :

import re
s = """if(condition_1)
{
....
some text
some text

if ((condition_1== condition_2)   ||
                 (condition_3== condition_4) ||
           (condition_6== condition_5)  ||
     (condition_7== condition_8)   ) // XYZ_variable
{
..."""
print( re.sub(r'(?m)^(\s*if\s*)(\(.*(?:\n(?!\s*if\s*\().*)*)//\s*(\w+)\s*$', r'\1(\2 || \3)', s) ) 

Вывод:

if(condition_1)
{
....
some text
some text

if (((condition_1== condition_2)   ||
                 (condition_3== condition_4) ||
           (condition_6== condition_5)  ||
     (condition_7== condition_8)   )  || XYZ_variable)
{
...
0 голосов
/ 21 марта 2019

Регулярное выражение захватывает первый соответствующий шаблон. Вот почему это всегда начинается с первого if.

Рассмотрим следующий минимальный пример, где не жадный ? не изменяет вывод:

>>> re.compile(r"if(.*?)XYZ").search("if a if b if c XYZ").group(1)
' a if b if c '

Но там не жадный ? изменяет вывод:

>>> re.compile(r"if(.*?)XYZ").search("if a XYZ if b if c XYZ").group(1)
' a '

Нежадный ? работает только в правой части поиска.

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