Verwendung des Python-Moduls für reguläre Ausdrücke re (match, search, sub, etc.)

Geschäft

Um reguläre Ausdrücke in Python zu verarbeiten, verwenden wir das Modul re aus der Standardbibliothek. Es ermöglicht das Extrahieren, Ersetzen und Aufteilen von Zeichenketten mit Hilfe regulärer Ausdrucksmuster.

In diesem Abschnitt werden zunächst die Funktionen und Methoden des re-Moduls erläutert.

  • Kompilieren regulärer Ausdrucksmuster:compile()
  • Match-Objekt
  • Prüfen, ob der Anfang der Zeichenkette übereinstimmt, extrahieren:match()
  • Suchen Sie nach Übereinstimmungen, die nicht auf den Anfang beschränkt sind:search()
  • Prüfen Sie, ob die gesamte Zeichenkette übereinstimmt:fullmatch()
  • Erhalten Sie eine Liste aller passenden Teile:findall()
  • Ermittelt alle übereinstimmenden Teile als Iterator:finditer()
  • Ersetzen Sie das passende Teil:sub(),subn()
  • Aufspaltung von Zeichenketten mit regulären Ausdrücken:split()

Danach erkläre ich die Metazeichen (Sonderzeichen) und spezielle Sequenzen von regulären Ausdrücken, die im Modul re verwendet werden können. Im Grunde handelt es sich um die Standard-Syntax für reguläre Ausdrücke, aber seien Sie vorsichtig beim Setzen von Flags (insbesondere re.ASCII).

  • Metazeichen für reguläre Ausdrücke, spezielle Sequenzen und Vorbehalte in Python
  • Setzen der Flagge
    • Begrenzt auf ASCII-Zeichen:re.ASCII
    • Groß- und Kleinschreibung wird nicht beachtet:re.IGNORECASE
    • Finde den Anfang und das Ende jeder Zeile:re.MULTILINE
    • Mehrere Flaggen angeben
  • Gierige und nicht-gierige Spiele

Kompilieren Sie das Muster des regulären Ausdrucks: compile()

Es gibt zwei Möglichkeiten, die Verarbeitung regulärer Ausdrücke im Modul re durchzuführen.

Lauf mit Funktion

Die erste ist eine Funktion.re.match(),re.sub()Funktionen wie diese stehen zur Verfügung, um Extraktionen, Ersetzungen und andere Prozesse unter Verwendung regulärer Ausdrucksmuster durchzuführen.

Die Details der Funktionen werden später beschrieben, aber bei allen ist das erste Argument die Zeichenkette des Musters des regulären Ausdrucks, gefolgt von der zu verarbeitenden Zeichenkette und so weiter. Bei re.sub() zum Beispiel, die eine Substitution durchführt, ist das zweite Argument die Substitutionszeichenfolge und das dritte Argument die zu verarbeitende Zeichenfolge.

import re

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

m = re.match(r'([a-z]+)@([a-z]+)\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

result = re.sub(r'([a-z]+)@([a-z]+)\.com', 'new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net

Beachten Sie, dass [a-z] im Muster des regulären Ausdrucks in diesem Beispiel ein beliebiges Zeichen von a bis z (d. h. Kleinbuchstaben) bedeutet, und + bedeutet, dass das vorherige Muster (in diesem Fall [a-z]) ein oder mehrere Male wiederholt wird. Das [a-z]+ passt zu jeder Zeichenfolge, die ein oder mehrere Kleinbuchstaben wiederholt.

. ist ein Metazeichen (ein Zeichen mit besonderer Bedeutung) und muss mit einem Backslash maskiert werden.

Da Musterzeichenketten für reguläre Ausdrücke oft viele Backslashes enthalten, ist es praktisch, rohe Zeichenketten wie im Beispiel zu verwenden.

Läuft in einer Methode eines Objekts mit regulärem Ausdrucksmuster

Die zweite Möglichkeit, reguläre Ausdrücke im Modul re zu verarbeiten, ist die Objektmethode für reguläre Ausdrucksmuster.

Mit re.compile() können Sie eine Musterzeichenkette für reguläre Ausdrücke kompilieren, um ein Musterobjekt für reguläre Ausdrücke zu erstellen.

p = re.compile(r'([a-z]+)@([a-z]+)\.com')

print(p)
# re.compile('([a-z]+)@([a-z]+)\\.com')

print(type(p))
# <class 're.Pattern'>

re.match(),re.sub()Zum Beispiel kann der gleiche Prozess wie diese Funktionen als Methoden match(), sub() von Objekten mit regulären Ausdrücken ausgeführt werden.

m = p.match(s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

result = p.sub('new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net

Alle unten beschriebenen re.xxx()-Funktionen werden auch als Methoden des Objekts für reguläre Ausdrücke bereitgestellt.

Wenn Sie einen Prozess wiederholen, der dasselbe Muster verwendet, ist es effizienter, mit re.compile() ein Objekt mit regulären Ausdrücken zu erzeugen und dieses zu verwenden.

Im folgenden Beispielcode wird die Funktion der Einfachheit halber ohne Kompilierung verwendet. Wenn Sie jedoch dasselbe Muster wiederholt verwenden möchten, empfiehlt es sich, die Funktion im Voraus zu kompilieren und als Methode eines Objekts mit regulärem Ausdruck auszuführen.

Match-Objekt

match(), search(), etc. geben ein Match-Objekt zurück.

s = 'aaa@xxx.com'

m = re.match(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(type(m))
# <class 're.Match'>

Die übereinstimmende Zeichenfolge und die Position werden mit den folgenden Methoden des Match-Objekts ermittelt.

  • Ermitteln Sie den Ort des Spiels:start(),end(),span()
  • Ermittelt die übereinstimmende Zeichenfolge:group()
  • Ermittelt die Zeichenfolge für jede Gruppe:groups()
print(m.start())
# 0

print(m.end())
# 11

print(m.span())
# (0, 11)

print(m.group())
# aaa@xxx.com

Wenn Sie einen Teil eines Musters eines regulären Ausdrucks in eine Zeichenkette mit Klammern() einschließen, wird der Teil als Gruppe verarbeitet. In diesem Fall kann die Zeichenkette des Teils, der auf jede Gruppe in groups() passt, als Tupel erhalten werden.

m = re.match(r'([a-z]+)@([a-z]+)\.([a-z]+)', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(m.groups())
# ('aaa', 'xxx', 'com')

Prüfen, ob der Anfang einer Zeichenkette übereinstimmt, Auszug: match()

match() gibt ein Match-Objekt zurück, wenn der Anfang der Zeichenkette mit dem Muster übereinstimmt.

Wie bereits erwähnt, kann das Match-Objekt verwendet werden, um die übereinstimmende Teilzeichenkette zu extrahieren oder einfach zu prüfen, ob eine Übereinstimmung erzielt wurde.

match() prüft nur den Anfang. Gibt es keine passende Zeichenkette am Anfang, wird None zurückgegeben.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

m = re.match(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

m = re.match(r'[a-z]+@[a-z]+\.net', s)
print(m)
# None

Suche nach Übereinstimmungen nicht auf den Anfang beschränkt, Auszug: search()

Wie match() gibt sie bei Übereinstimmung ein Match-Objekt zurück.

Wenn es mehrere übereinstimmende Teile gibt, wird nur der erste übereinstimmende Teil zurückgegeben.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

m = re.search(r'[a-z]+@[a-z]+\.net', s)
print(m)
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>

m = re.search(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

Wenn Sie alle übereinstimmenden Teile erhalten möchten, verwenden Sie findall() oder finditer() wie unten beschrieben.

Prüfen, ob die gesamte Zeichenkette übereinstimmt: fullmatch()

Um zu prüfen, ob die gesamte Zeichenkette mit dem Muster des regulären Ausdrucks übereinstimmt, verwenden Sie fullmatch(). Dies ist z. B. nützlich, um zu prüfen, ob eine Zeichenkette als E-Mail-Adresse gültig ist oder nicht.

Wenn die gesamte Zeichenkette übereinstimmt, wird ein Match-Objekt zurückgegeben.

s = 'aaa@xxx.com'

m = re.fullmatch(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

Wenn es nicht übereinstimmende Teile gibt (nur teilweise oder gar keine Übereinstimmungen), wird None zurückgegeben.

s = '!!!aaa@xxx.com!!!'

m = re.fullmatch(r'[a-z]+@[a-z]+\.com', s)
print(m)
# None

Die Funktion fullmatch() wurde in Python 3.4 eingeführt. Wenn Sie dasselbe in früheren Versionen tun wollen, verwenden Sie match() und ein passendes Metazeichen $ am Ende. Wenn die gesamte Zeichenkette vom Anfang bis zum Ende nicht übereinstimmt, wird None zurückgegeben.

s = '!!!aaa@xxx.com!!!'

m = re.match(r'[a-z]+@[a-z]+\.com$', s)
print(m)
# None

Eine Liste aller übereinstimmenden Teile erhalten: findall()

findall() gibt eine Liste aller übereinstimmenden Teilzeichenfolgen zurück. Beachten Sie, dass die Elemente der Liste keine Übereinstimmungsobjekte, sondern Zeichenketten sind.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

result = re.findall(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(result)
# ['aaa@xxx.com', 'bbb@yyy.com', 'ccc@zzz.net']

Die Anzahl der übereinstimmenden Teile kann mit der eingebauten Funktion len() überprüft werden, die die Anzahl der Elemente in der Liste zurückgibt.

print(len(result))
# 3

Die Gruppierung mit Klammern() in einem Muster für reguläre Ausdrücke gibt eine Liste von Tupeln zurück, deren Elemente die Zeichenketten der einzelnen Gruppen sind. Dies ist äquivalent zu groups() im match-Objekt.

result = re.findall(r'([a-z]+)@([a-z]+)\.([a-z]+)', s)
print(result)
# [('aaa', 'xxx', 'com'), ('bbb', 'yyy', 'com'), ('ccc', 'zzz', 'net')]

Die Gruppenklammern () können verschachtelt werden. Wenn Sie also auch die gesamte Übereinstimmung erhalten möchten, schließen Sie die gesamte Übereinstimmung in Klammern () ein.

result = re.findall(r'(([a-z]+)@([a-z]+)\.([a-z]+))', s)
print(result)
# [('aaa@xxx.com', 'aaa', 'xxx', 'com'), ('bbb@yyy.com', 'bbb', 'yyy', 'com'), ('ccc@zzz.net', 'ccc', 'zzz', 'net')]

Wenn keine Übereinstimmung gefunden wird, wird ein leeres Tupel zurückgegeben.

result = re.findall('[0-9]+', s)
print(result)
# []

Alle übereinstimmenden Teile als Iterator ermitteln: finditer()

finditer() gibt alle übereinstimmenden Teile als Iterator zurück. Die Elemente sind keine Strings wie findall(), sondern Match-Objekte, so dass Sie die Position (Index) der übereinstimmenden Teile erhalten können.

Der Iterator selbst kann nicht mit print() ausgedruckt werden, um seinen Inhalt zu erhalten. Wenn Sie die eingebaute Funktion next() oder die for-Anweisung verwenden, können Sie den Inhalt der Reihe nach abrufen.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

result = re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(result)
# <callable_iterator object at 0x10b0efa90>

print(type(result))
# <class 'callable_iterator'>

for m in result:
    print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
# <re.Match object; span=(13, 24), match='bbb@yyy.com'>
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>

Sie kann auch mit list() in eine Liste umgewandelt werden.

l = list(re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s))
print(l)
# [<re.Match object; span=(0, 11), match='aaa@xxx.com'>, <re.Match object; span=(13, 24), match='bbb@yyy.com'>, <re.Match object; span=(26, 37), match='ccc@zzz.net'>]

print(l[0])
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(type(l[0]))
# <class 're.Match'>

print(l[0].span())
# (0, 11)

Wenn Sie die Position aller übereinstimmenden Teile abfragen wollen, ist die Listenauffassungsnotation bequemer als list().

print([m.span() for m in re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)])
# [(0, 11), (13, 24), (26, 37)]

Der Iterator entnimmt die Elemente der Reihe nach. Wenn Sie versuchen, weitere Elemente zu entnehmen, nachdem Sie das Ende erreicht haben, bleibt nichts übrig.

result = re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)

for m in result:
    print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
# <re.Match object; span=(13, 24), match='bbb@yyy.com'>
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>

print(list(result))
# []

Ersetzen Sie die übereinstimmenden Teile: sub(), subn()

Mit sub() können Sie den übereinstimmenden Teil durch eine andere Zeichenfolge ersetzen. Die ersetzte Zeichenkette wird zurückgegeben.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

result = re.sub(r'[a-z]+@[a-z]+\.com', 'new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net

print(type(result))
# <class 'str'>

Bei der Gruppierung mit Klammern() kann die übereinstimmende Zeichenfolge in der ersetzten Zeichenfolge verwendet werden.

Standardmäßig wird das Folgende unterstützt: Beachten Sie, dass bei normalen Zeichenketten, die keine rohen Zeichenketten sind, ein Backslash vor dem Backslash aufgeführt werden muss, um den Backslash zu umgehen.

\1Die erste Klammer
\2Die zweite Klammer
\3Die dritte Klammer
result = re.sub(r'([a-z]+)@([a-z]+)\.com', r'\1@\2.net', s)
print(result)
# aaa@xxx.net, bbb@yyy.net, ccc@zzz.net

?P<xxx>
Wenn Sie die Gruppe benennen, indem Sie dies am Anfang der Klammern des Musters für den regulären Ausdruck schreiben, können Sie den Namen anstelle der Nummer angeben, wie unten gezeigt.
\g<xxx>

result = re.sub(r'(?P<local>[a-z]+)@(?P<SLD>[a-z]+)\.com', r'\g<local>@\g<SLD>.net', s)
print(result)
# aaa@xxx.net, bbb@yyy.net, ccc@zzz.net

Das Argument count gibt die maximale Anzahl der Ersetzungen an. Es wird nur die Anzahl von der linken Seite ersetzt.

result = re.sub(r'[a-z]+@[a-z]+\.com', 'new-address', s, count=1)
print(result)
# new-address, bbb@yyy.com, ccc@zzz.net

subn() gibt ein Tupel zurück, das die ersetzte Zeichenkette (wie der Rückgabewert von sub()) und die Anzahl der ersetzten Teile (die Anzahl, die mit dem Muster übereinstimmt) enthält.

result = re.subn(r'[a-z]+@[a-z]+\.com', 'new-address', s)
print(result)
# ('new-address, new-address, ccc@zzz.net', 2)

Die Methode zur Angabe von Argumenten ist dieselbe wie bei sub(). Sie können den durch Klammern gruppierten Teil verwenden oder die Anzahl der Argumente angeben.

result = re.subn(r'(?P<local>[a-z]+)@(?P<SLD>[a-z]+)\.com', r'\g<local>@\g<SLD>.net', s)
print(result)
# ('aaa@xxx.net, bbb@yyy.net, ccc@zzz.net', 2)

result = re.subn(r'[a-z]+@[a-z]+\.com', 'new-address', s, count=1)
print(result)
# ('new-address, bbb@yyy.com, ccc@zzz.net', 1)

Zerlegen von Zeichenketten mit regulären Ausdrücken: split()

split() teilt die Zeichenkette an dem Teil auf, der dem Muster entspricht, und gibt sie als Liste zurück.

Beachten Sie, dass die erste und die letzte Übereinstimmung leere Zeichenfolgen am Anfang und am Ende der resultierenden Liste enthalten.

s = '111aaa222bbb333'

result = re.split('[a-z]+', s)
print(result)
# ['111', '222', '333']

result = re.split('[0-9]+', s)
print(result)
# ['', 'aaa', 'bbb', '']

Das Argument maxsplit gibt die maximale Anzahl der Splits (Stücke) an. Es wird nur die Anzahl von der linken Seite geteilt.

result = re.split('[a-z]+', s, 1)
print(result)
# ['111', '222bbb333']

Metazeichen für reguläre Ausdrücke, spezielle Sequenzen und Vorbehalte in Python

Die wichtigsten Metazeichen für reguläre Ausdrücke (Sonderzeichen) und spezielle Sequenzen, die im Python 3 re-Modul verwendet werden können, sind folgende

MetacharakterInhalt
.Jedes einzelne Zeichen außer einem Zeilenumbruch (einschließlich eines Zeilenumbruchs mit dem DOTALL-Flag)
^Der Anfang der Zeichenkette (entspricht auch dem Anfang jeder Zeile mit dem MULTILINE-Flag)
$Das Ende der Zeichenkette (entspricht auch dem Ende jeder Zeile mit dem MULTILINE-Flag)
*Wiederholen Sie das vorherige Muster mehr als 0 Mal
+Wiederholen Sie das vorherige Muster mindestens einmal.
?Wiederholen Sie das vorherige Muster 0 oder 1 Mal
{m}Wiederholen Sie das vorherige Muster m-mal
{m, n}Das letzte Muster.m~nwiederholen
[]Eine Reihe von Zeichen[]Entspricht einem der folgenden Zeichen
|ORA|BEntspricht entweder dem Muster A oder B
besondere ReihenfolgeInhalt
\dUnicode-Dezimalzahlen (begrenzt auf ASCII-Zahlen durch ASCII-Flag)
\D\dDas bedeutet das Gegenteil davon.
\sUnicode-Whitespace-Zeichen (begrenzt auf ASCII-Whitespace-Zeichen durch ASCII-Flag)
\S\sDas bedeutet das Gegenteil davon.
\wUnicode-Wortzeichen und Unterstriche (begrenzt auf alphanumerische ASCII-Zeichen und Unterstriche durch ASCII-Flag)
\W\wDas bedeutet das Gegenteil davon.

Nicht alle von ihnen sind in dieser Tabelle aufgeführt. Eine vollständige Liste finden Sie in der offiziellen Dokumentation.

Beachten Sie auch, dass einige der Bedeutungen in Python 2 anders sind.

Setzen der Flagge

Wie in der obigen Tabelle dargestellt, ändern einige Metazeichen und Sonderzeichenfolgen ihren Modus je nach Flagge.

Hier werden nur die wichtigsten Flaggen behandelt. Den Rest finden Sie in der offiziellen Dokumentation.

Begrenzt auf ASCII-Zeichen: re.ASCII

\wDies entspricht auch Doppelbyte-Kanji, alphanumerischen Zeichen usw. standardmäßig für Python 3-Zeichenfolgen. Er ist nicht äquivalent zu folgendem, da es sich nicht um einen regulären Standardausdruck handelt.[a-zA-Z0-9_]

m = re.match(r'\w+', '漢字ABC123')
print(m)
# <re.Match object; span=(0, 11), match='漢字ABC123'>

m = re.match('[a-zA-Z0-9_]+', '漢字ABC123')
print(m)
# None

Wenn Sie re.ASCII für die Argumentflags in jeder Funktion angeben oder das folgende Inline-Flag an den Anfang der Musterzeichenkette für reguläre Ausdrücke anhängen, werden nur ASCII-Zeichen gefunden (keine japanischen Doppelbyte-Zeichen, alphanumerische Zeichen usw.).
(?a)
In diesem Fall sind die beiden folgenden gleichwertig.
\w=[a-zA-Z0-9_]

m = re.match(r'\w+', '漢字ABC123', flags=re.ASCII)
print(m)
# None

m = re.match(r'(?a)\w+', '漢字ABC123')
print(m)
# None

Dasselbe gilt für die Kompilierung mit re.compile(). Verwenden Sie das Argument Flags oder Inline-Flags.

p = re.compile(r'\w+', flags=re.ASCII)
print(p)
# re.compile('\\w+', re.ASCII)

print(p.match('漢字ABC123'))
# None

p = re.compile(r'(?a)\w+')
print(p)
# re.compile('(?a)\\w+', re.ASCII)

print(p.match('漢字ABC123'))
# None

ASCII ist auch in der Kurzform re verfügbar. A. Sie können beides verwenden.

print(re.ASCII is re.A)
# True

\W, das Gegenteil von \W, wird auch von re.ASCII und Inline-Flags beeinflusst.

m = re.match(r'\W+', '漢字ABC123')
print(m)
# None

m = re.match(r'\W+', '漢字ABC123', flags=re.ASCII)
print(m)
# <re.Match object; span=(0, 11), match='漢字ABC123'>

Wie bei \w passen die beiden folgenden standardmäßig sowohl auf Ein-Byte- als auch auf Zwei-Byte-Zeichen, sind aber auf Ein-Byte-Zeichen beschränkt, wenn re.ASCII oder Inline-Flags angegeben sind.

  • Stimmen Sie die Zahlen ab\d
  • Stimmt mit einem Leerzeichen überein\s
  • Entspricht Nicht-Zahlen\D
  • Passt auf jedes Nicht-Leerzeichen.\S
m = re.match(r'\d+', '123')
print(m)
# <re.Match object; span=(0, 3), match='123'>

m = re.match(r'\d+', '123')
print(m)
# <re.Match object; span=(0, 3), match='123'>

m = re.match(r'\d+', '123', flags=re.ASCII)
print(m)
# <re.Match object; span=(0, 3), match='123'>

m = re.match(r'\d+', '123', flags=re.ASCII)
print(m)
# None

m = re.match(r'\s+', ' ')  # full-width space
print(m)
# <re.Match object; span=(0, 1), match='\u3000'>

m = re.match(r'\s+', ' ', flags=re.ASCII)
print(m)
# None

Groß- und Kleinschreibung wird nicht beachtet:re.IGNORECASE

Standardmäßig wird zwischen Groß- und Kleinschreibung unterschieden. Um beides abzugleichen, müssen Sie sowohl Groß- als auch Kleinbuchstaben in das Muster aufnehmen.

re.IGNORECASEWenn dies angegeben ist, wird die Groß- und Kleinschreibung nicht berücksichtigt. Entspricht dem i-Flag in regulären Standardausdrücken.

m = re.match('[a-zA-Z]+', 'abcABC')
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>

m = re.match('[a-z]+', 'abcABC', flags=re.IGNORECASE)
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>

m = re.match('[A-Z]+', 'abcABC', flags=re.IGNORECASE)
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>

Sie können “kleiner als” oder “gleich” verwenden.

  • Inline-Kennzeichen(?i)
  • Abkürzungre.I

Finde den Anfang und das Ende jeder Zeile:re.MULTILINE

^Die Metazeichen in diesem regulären Ausdruck entsprechen dem Anfang der Zeichenfolge.

Standardmäßig wird nur der Anfang der gesamten Zeichenkette abgeglichen, aber die folgende Option passt auch auf den Anfang jeder Zeile. Äquivalent zum m-Flag in regulären Ausdrücken.
re.MULTILINE

s = '''aaa-xxx
bbb-yyy
ccc-zzz'''

print(s)
# aaa-xxx
# bbb-yyy
# ccc-zzz

result = re.findall('[a-z]+', s)
print(result)
# ['aaa', 'xxx', 'bbb', 'yyy', 'ccc', 'zzz']

result = re.findall('^[a-z]+', s)
print(result)
# ['aaa']

result = re.findall('^[a-z]+', s, flags=re.MULTILINE)
print(result)
# ['aaa', 'bbb', 'ccc']

$Stimmt mit dem Ende der Zeichenfolge überein. Standardmäßig wird nur das Ende der gesamten Zeichenfolge abgeglichen.
re.MULTILINEWenn Sie dies angeben, wird auch das Ende einer jeden Zeile berücksichtigt.

result = re.findall('[a-z]+$', s)
print(result)
# ['zzz']

result = re.findall('[a-z]+$', s, flags=re.MULTILINE)
print(result)
# ['xxx', 'yyy', 'zzz']

Sie können “kleiner als” oder “gleich” verwenden.

  • Inline-Kennzeichen(?m)
  • Abkürzungre.M

Mehrere Flaggen angeben

|Wenn Sie mehrere Flaggen gleichzeitig aktivieren wollen, verwenden Sie dies. Bei Inline-Flags muss auf jedes Zeichen ein Buchstabe folgen, wie unten gezeigt.
(?am)

s = '''aaa-xxx
漢漢漢-字字字
bbb-zzz'''

print(s)
# aaa-xxx
# 漢漢漢-字字字
# bbb-zzz

result = re.findall(r'^\w+', s, flags=re.M)
print(result)
# ['aaa', '漢漢漢', 'bbb']

result = re.findall(r'^\w+', s, flags=re.M | re.A)
print(result)
# ['aaa', 'bbb']

result = re.findall(r'(?am)^\w+', s)
print(result)
# ['aaa', 'bbb']

Gierige und nicht-gierige Spiele

Dies ist ein allgemeines Problem mit regulären Ausdrücken, nicht nur ein Problem mit Python, aber ich werde darüber schreiben, weil es dazu neigt, mich in Schwierigkeiten zu bringen.

Standardmäßig handelt es sich bei der folgenden Angabe um eine “gierige” Übereinstimmung, die auf die längste mögliche Zeichenfolge zutrifft.

  • *
  • +
  • ?
s = 'aaa@xxx.com, bbb@yyy.com'

m = re.match(r'.+com', s)
print(m)
# <re.Match object; span=(0, 24), match='aaa@xxx.com, bbb@yyy.com'>

print(m.group())
# aaa@xxx.com, bbb@yyy.com

Das nachfolgende ? führt zu einer nicht gierigen Minimalübereinstimmung, die die kürzestmögliche Zeichenkette enthält.

  • *?
  • +?
  • ??
m = re.match(r'.+?com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(m.group())
# aaa@xxx.com

Beachten Sie, dass die standardmäßige gierige Übereinstimmung mit unerwarteten Zeichenfolgen übereinstimmen kann.