Преобразование регулярных выражений Perl в регулярные выражения Python - PullRequest
4 голосов
/ 24 января 2011

У меня проблемы с преобразованием регулярного выражения Perl в Python.Текст, который я пытаюсь сопоставить, имеет следующий шаблон:

Author(s)    : Firstname Lastname  
               Firstname Lastname  
               Firstname Lastname  
               Firstname Lastname

В Perl мне удалось сопоставить это и извлечь авторов с помощью

/Author\(s\)    :((.+\n)+?)/

Когда я пытаюсь

re.compile(r'Author\(s\)    :((.+\n)+?)')

в Python, он соответствует первому автору дважды и игнорирует остальные.

Может кто-нибудь объяснить, что я здесь делаю неправильно?

Ответы [ 3 ]

3 голосов
/ 24 января 2011

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

# find lines with authors
import re

# multiline string to simulate possible input
text = '''
Stuff before
This won't be matched...
Author(s)    : Firstname Lastname  
               Firstname Lastname  
               Firstname Lastname  
               Firstname Lastname
Other(s)     : Something else we won't match
               More shenanigans....
Only the author names will be matched.
'''

# run the regex to pull author lines from the sample input
authors = re.search(r'Author\(s\)\s*:\s*(.*?)^[^\s]', text, re.DOTALL | re.MULTILINE).group(1)

Приведенное выше регулярное выражение соответствует начальному тексту (Автор (ы), пробел, двоеточие, пробел) и дает вам следующие результатысопоставляя все строки, начинающиеся с пробела:

'''Firstname Lastname  
           Firstname Lastname  
           Firstname Lastname  
           Firstname Lastname
'''

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

# grab authors from the lines
import re
authors = '''Firstname Lastname  
           Firstname Lastname  
           Firstname Lastname  
           Firstname Lastname
'''

# run the regex to pull a list of individual authors from the author lines
authors = re.findall(r'^\s*(.+?)\s*$', authors, re.MULTILINE)

, что дает вам список авторов:

['Firstname Lastname', 'Firstname Lastname', 'Firstname Lastname', 'Firstname Lastname']

Комбинированный пример кода:

text = '''
Stuff before
This won't be matched...
Author(s)    : Firstname Lastname  
               Firstname Lastname  
               Firstname Lastname  
               Firstname Lastname
Other(s)     : Something else we won't match
               More shenanigans....
Only the author names will be matched.
'''

import re
stage1 = re.compile(r'Author\(s\)\s*:\s*(.*?)^[^\s]', re.DOTALL | re.MULTILINE)
stage2 = re.compile('^\s*(.+?)\s*$', re.MULTILINE)

preliminary = stage1.search(text).group(1)
authors = stage2.findall(preliminary)

, который устанавливает авторов:

['Firstname Lastname', 'Firstname Lastname', 'Firstname Lastname', 'Firstname Lastname']

Успех!

2 голосов
/ 24 января 2011

Одна группа может соответствовать только один раз.Таким образом, даже если ваша группа соответствия повторяется, вы можете получить доступ только к последнему фактическому совпадению.Вам нужно будет сопоставить все имена сразу и затем разделить их (через новую строку или даже новые регулярные выражения).

1 голос
/ 24 января 2011

Попробуйте

re.compile(r'Author\(s\)    :((.+\n)+)')

В исходном выражении +? означало, что вы хотите, чтобы совпадение было не жадным, то есть минимальным.

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