2016-10-18 3 views
0

следующим выражением хорошо работает извлекая часть data строки, которая начинается со словом Block с последующим открывающей скобкой { и заканчивая закрывающую скобкой «}»:Как использовать Regex с многострочным

data =""" 
Somewhere over the rainbow 
Way up high 
Block { 
line 1 
line 2 
line 3 
} 
And the dreams that you dreamed of 
Once in a lullaby 
""" 
regex = re.compile("""(Block\ {\n\ [^\{\}]*\n}\n)""", re.MULTILINE) 
result = regex.findall(data) 
print result 

который возвращает :

['Block {\n line 1\n line 2\n line 3\n}\n'] 

Но если есть другая фигурная скобка внутри блок части строки экспрессирующих брейки возвращающихся пустой список:

data =""" 
Somewhere over the rainbow 
Way up high 
Block { 
line 1 
line 2 
{{} 
line 3 
} 
And the dreams that you dreamed of 
Once in a lullaby 
Block { 
line 4 
line 5 
{{ 
} 
line 6 
} 
Somewhere over the rainbow 
Blue birds fly 
And the dreams that you dreamed of 
Dreams really do come true ooh oh 
""" 

Как изменить это регулярное выражение, чтобы сделать его игнорировать скобки, которые находятся внутри блоков, и все же каждый блок возвращается как отдельное юридическое лицо в result списка (так что каждый блок может быть доступна отдельно)?

+0

На самом деле '[^ {}] *' предотвращает, чтобы соответствовать любой открывающую фигурную скобку. Обратите внимание, что флаг MULTILINE - это не то, что вы думаете. * (это не для совпадающих строк, которые распространяются по нескольким строкам, это только изменяет значение якорей '^' и '$'. Чтобы точка совпадала с символами новой строки, флаг DOTALL) * –

+0

Поскольку вы редактировали свой вопрос : эта проблема не может быть решена с помощью модуля re, вам нужен модуль * regex *, который обрабатывает рекурсию. Обратите внимание, что вам нужно выбрать поведение по умолчанию для неопределенных случаев. –

ответ

1

Не так ли?

regex = re.compile("""(Block\ {\n\ [^\}]*\n}\n)""", re.MULTILINE)

В версии вы в курсе, он покидает матч, когда он попадается второй открывающей скобкой, даже если вы хотите, чтобы выйти на первой закрывающей скобкой. Если вы хотите, чтобы вложенные открывающие/закрывающие фигурные скобки были другой историей.

+0

Ваше выражение вернет пустой список, если есть внутренняя скобка '}' Чтобы проиллюстрировать это, я немного изменил свой код, чтобы включить '{{}' внутри блока. – alphanumeric

+0

Что конкретно закрывает блок? '\ П \} \ n'? – cchamberlain

+0

Да, блок всегда закрыт '\ n \} \ n'. И он всегда начинается с 'Block \ {\ n' – alphanumeric

0

Я хотел бы предложить вам использовать:

(Block ?{\n ?[^$]+?\n}\n) 

Поскольку питона спичек жадный, мы используем ? быть неживым.

Работал хорошо для меня. Кроме того, я бы рекомендовал вам использовать https://regex101.com/

С наилучшими пожеланиями

+0

Спасибо за ответ! Но ваше выражение возвращает оба блока как единый объект в списке. Он рассматривает только первую скобку и последнюю скобку. – alphanumeric

+0

Вы отредактировали свой код! Это был не первый вопрос, на который вы ответили ... – 1574ad6

+0

С твоими модификациями это хорошо работает: (Block? {\ N? [^ $] +? \ N} \ n) – 1574ad6

Смежные вопросы