2016-08-19 3 views
2

Так что я пытаюсь захватить строку из BibTex, используя regex в python. Вот часть моей строки:python regex найти совпадение, которое охватывает несколько строк

a = '''title = {The Origin ({S}, 
     {Se}, and {Te})- {TiO$_2$} Photocatalysts}, 
    year = {2010}, 
    volume = {114},''' 

Я хочу, чтобы захватить строку для заголовка, который:

The Origin ({S}, 
     {Se}, and {Te})- {TiO$_2$} Photocatalysts 

Сейчас у меня этот код:

pattern = re.compile('title\s*=\s*{(.*|\n?)},\s*\n', re.DOTALL|re.I) 
pattern.findall(a) 

Но только это дает мне:

['The Origin ({S},\n   {Se}, and {Te})- {TiO$_2$} Photocatalysts},\n  year = {2010'] 

Как я могу получить всю строку заголовка без информации year? Много раз, year не сразу после title. Поэтому я не могу использовать:

pattern = re.compile('title\s*=\s*{(.*|\n?)},\s*\n.*year', re.DOTALL|re.I) 
pattern.findall(a) 
+0

Возможный дубликат http://stackoverflow.com/questions/587345/python-regular-expression-matching-a-multiline-block-of-text –

+0

Я пробовал это, но все еще не мог решить свою проблему. –

ответ

1

быстрое решение было бы изменить ваш шаблон регулярного выражения

pattern = re.compile('title\s*=\s*{(.*|\n?)},\s*\n', re.DOTALL|re.I) 
+0

Я только что узнал, что это неправильно. Он также возьмет линию «год» –

1

Зависит от того, как вообще вы хотите, чтобы ваше регулярное выражение будет. Я думаю, вы хотите, чтобы ваша строка была в состоянии содержать {и}, поэтому использование этого для обозначения окончания шаблона вызовет проблемы. Также могут быть несколько скобок.

Вот идея, что если вы ищете слово year в конце регулярного выражения, считая, что оно постоянное.

pattern = re.compile('title\s*=\s*{(.*?)},\s*\n\s*year', re.DOTALL|re.I) 
+0

Много раз «год» не после 'title'. Но вы все еще даете мне новое представление об этом :) –

0

textwrap может быть полезным:

import textwrap 

a = '''title = {The Origin ({S}, 
     {Se}, and {Te})- {TiO$_2$} Photocatalysts}, 
    year = {2010}, 
    volume = {114},''' 

indent = " " 
print(textwrap.dedent(indent + a)) 
1

Используйте новый regex module:

import regex as re 

rx = re.compile(r''' 
     (?(DEFINE) 
      (?<part>\w+\ =\ \{) 
      (?<end>\},) 
      (?<title>title\ =\ \{) 
     ) 
     (?&title)(?P<t>(?:(?!(?&part))[\s\S])+)(?&end) 
    ''', re.VERBOSE) 

string = ''' 
title = {The Origin ({S}, 
     {Se}, and {Te})- {TiO$_2$} Photocatalysts}, 
    year = {2010}, 
    volume = {114}, 
''' 

title = rx.search(string).group('t') 
print(title) 
# The Origin ({S}, 
# {Se}, and {Te})- {TiO$_2$} Photocatalysts 

Хотя это на самом деле не нужен, он обеспечивает альтернативное решение.

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