4 Stimmen

Umwandlung regulärer Ausdrücke aus Perl in reguläre Ausdrücke aus Python

Ich habe Probleme bei der Konvertierung einer Perl-Regex in Python. Der Text, den ich abgleichen will, hat das folgende Muster:

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

In Perl konnte ich dies abgleichen und die Autoren extrahieren mit

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

Wenn ich versuche

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

in Python wird der erste Autor zweimal gefunden und der Rest ignoriert.

Kann mir jemand erklären, was ich hier falsch mache?

3voto

lunixbochs Punkte 20277

Sie können dies tun:

# 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)

Die obige Regex stimmt mit dem Anfangstext überein (Autor(en), Leerzeichen, Doppelpunkt, Leerzeichen) und liefert die folgenden Ergebnisse, indem sie alle nachfolgenden Zeilen abgleicht, die mit Leerzeichen beginnen:

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

Sie können dann die folgende Regex verwenden, um alle Autoren aus diesen Ergebnissen zu gruppieren

# 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)

So erhalten Sie die Liste der Autoren:

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

Kombinierter Beispielcode:

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)

Was die Autoren dazu veranlasst:

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

Erfolgreich!

2voto

poke Punkte 338075

Eine Gruppe kann nur ein einziges Mal übereinstimmen. Selbst wenn Ihre passende Gruppe wiederholt wird, können Sie also nur auf die letzte tatsächliche Übereinstimmung zugreifen. Sie müssen alle Namen auf einmal abgleichen und sie dann aufteilen (durch Zeilenumbruch oder sogar neue Regexps).

1voto

Martin v. Löwis Punkte 120025

Versuchen Sie

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

In Ihrem ursprünglichen Ausdruck ist die +? angegeben, dass die Übereinstimmung nicht gierig, d. h. minimal sein soll.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X