Reguläre Ausdrücke
Ein regulärer Ausdruck (kurz Regex [...]) ist eine Zeichenfolge, die ein Suchmuster in Text definiert. [...] wird von String-Suchalgorithmen für "Suchen" oder "Suchen und Ersetzen"-Operationen an Strings oder zur Eingabevalidierung verwendet.
- Importieren Sie das Regex-Modul mit
import re. - Erstellen Sie ein Regex-Objekt mit der Funktion
re.compile(). (Denken Sie daran, einen Raw String zu verwenden.) - Übergeben Sie den String, den Sie durchsuchen möchten, an die
search()-Methode des Regex-Objekts. Dies gibt einMatch-Objekt zurück. - Rufen Sie die
group()-Methode des Match-Objekts auf, um einen String des tatsächlich gefundenen Textes zurückzugeben.
Alle Regex-Funktionen in Python befinden sich im re-Modul:
# Importieren Sie das re-Modul für Operationen mit regulären Ausdrücken
import re
Regex-Symbole
| Symbol | Entspricht |
|---|---|
? | Null oder eine Wiederholung der vorangehenden Gruppe. |
* | Null oder mehr Wiederholungen der vorangehenden Gruppe. |
+ | Eine oder mehr Wiederholungen der vorangehenden Gruppe. |
{n} | Genau n Wiederholungen der vorangehenden Gruppe. |
{n,} | n oder mehr Wiederholungen der vorangehenden Gruppe. |
{,m} | 0 bis m Wiederholungen der vorangehenden Gruppe. |
{n,m} | Mindestens n und höchstens m Wiederholungen der vorangehenden Gruppe. |
{n,m}? oder *? oder +? | Führt eine nicht-gierige Übereinstimmung der vorangehenden Gruppe durch. |
^spam | Bedeutet, der String muss mit spam beginnen. |
spam$ | Bedeutet, der String muss mit spam enden. |
. | Beliebiges Zeichen, außer Zeilenumbruchzeichen. |
\d, \w, und \s | Eine Ziffer, ein Wortzeichen bzw. ein Leerzeichen. |
\D, \W, und \S | Alles außer einer Ziffer, einem Wortzeichen bzw. einem Leerzeichen. |
[abc] | Ein beliebiges Zeichen zwischen den Klammern (wie a, b, ). |
[^abc] | Ein beliebiges Zeichen, das nicht zwischen den Klammern steht. |
Matching Regex-Objekte
# re.compile(): Regex-Musterobjekt erstellen (Raw String r'' verwenden, um Escaping zu vermeiden)
phone_num_regex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') # Muster: 3 Ziffern-3 Ziffern-4 Ziffern
mo = phone_num_regex.search('Meine Nummer ist 415-555-4242.') # Nach Muster suchen
print(f'Telefonnummer gefunden: {mo.group()}') # group() gibt den gefundenen Text zurück
Phone number found: 415-555-4242
Gruppierung mit Klammern
# Klammern erstellen Gruppen: group(1) gibt die erste Gruppe zurück, group(2) die zweite
phone_num_regex = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)') # Zwei Gruppen in Klammern
mo = phone_num_regex.search('Meine Nummer ist 415-555-4242.')
mo.group(1) # Gibt die erste Gruppe zurück: '415'
'415'
mo.group(2)
'555-4242'
mo.group(0)
'415-555-4242'
mo.group()
'415-555-4242'
Melden Sie sich an, um dieses Quiz zu beantworten und Ihren Lernfortschritt zu verfolgen
group() zurück, wenn es auf ein Match-Objekt aufgerufen wird?Um alle Gruppen auf einmal abzurufen, verwenden Sie die Methode groups():
# groups(): gibt ein Tupel aller Gruppen zurück
mo.groups() # Gibt ('415', '555-4242') zurück
('415', '555-4242')
area_code, main_number = mo.groups()
print(area_code)
415
print(main_number)
555-4242
Mehrere Gruppen mit Pipe
Sie können das Zeichen | überall dort verwenden, wo Sie eine von vielen Ausdrücken abgleichen möchten.
hero_regex = re.compile (r'Batman|Tina Fey')
mo1 = hero_regex.search('Batman und Tina Fey.')
mo1.group()
'Batman'
mo2 = hero_regex.search('Tina Fey und Batman.')
mo2.group()
'Tina Fey'
Sie können die Pipe auch verwenden, um eine von mehreren Mustern als Teil Ihres Regex abzugleichen:
bat_regex = re.compile(r'Bat(man|mobile|copter|bat)')
mo = bat_regex.search('Batmobile verlor ein Rad')
mo.group()
'Batmobile'
mo.group(1)
'mobile'
Optionale Übereinstimmung mit dem Fragezeichen
Das Zeichen ? kennzeichnet die ihm vorangehende Gruppe als optionalen Teil des Musters.
bat_regex = re.compile(r'Bat(wo)?man')
mo1 = bat_regex.search('Die Abenteuer von Batman')
mo1.group()
'Batman'
mo2 = bat_regex.search('Die Abenteuer von Batwoman')
mo2.group()
'Batwoman'
Übereinstimmung von Null oder mehr mit dem Sternchen
Das * (Sternchen) bedeutet “null oder mehr Übereinstimmungen”. Die Gruppe, der der Stern vorangestellt ist, kann beliebig oft im Text vorkommen.
bat_regex = re.compile(r'Bat(wo)*man')
mo1 = bat_regex.search('Die Abenteuer von Batman')
mo1.group()
'Batman'
mo2 = bat_regex.search('Die Abenteuer von Batwoman')
mo2.group()
'Batwoman'
mo3 = bat_regex.search('Die Abenteuer von Batwowowowoman')
mo3.group()
'Batwowowowoman'
Übereinstimmung von Eins oder mehr mit dem Plus
Das + (Plus) bedeutet “eine oder mehr Übereinstimmungen”. Der Gruppe, der ein Plus vorangestellt ist, muss mindestens einmal vorkommen:
bat_regex = re.compile(r'Bat(wo)+man')
mo1 = bat_regex.search('Die Abenteuer von Batwoman')
mo1.group()
'Batwoman'
mo2 = bat_regex.search('Die Abenteuer von Batwowowowoman')
mo2.group()
'Batwowowowoman'
mo3 = bat_regex.search('Die Abenteuer von Batman')
mo3 is None
True
Übereinstimmung spezifischer Wiederholungen mit geschweiften Klammern
Wenn Sie eine Gruppe haben, die Sie eine bestimmte Anzahl von Malen wiederholen möchten, folgen Sie der Gruppe in Ihrem Regex mit einer Zahl in geschweiften Klammern:
ha_regex = re.compile(r'(Ha){3}')
mo1 = ha_regex.search('HaHaHa')
mo1.group()
'HaHaHa'
mo2 = ha_regex.search('Ha')
mo2 is None
True
Anstelle einer einzelnen Zahl können Sie einen Bereich mit einem Minimum und einem Maximum zwischen den geschweiften Klammern angeben. Zum Beispiel gleicht der Regex (Ha){3,5} ‘HaHaHa’, ‘HaHaHaHa’ und ‘HaHaHaHaHa’ ab.
ha_regex = re.compile(r'(Ha){2,3}')
mo1 = ha_regex.search('HaHaHaHa')
mo1.group()
'HaHaHa'
Gierige und nicht-gierige Übereinstimmungen
Die regulären Ausdrücke von Python sind standardmäßig gierig (greedy): In mehrdeutigen Situationen versuchen sie, die längstmögliche Zeichenfolge abzugleichen. Die nicht-gierige Version der geschweiften Klammern, die die kürzestmögliche Zeichenfolge abgleicht, hat die schließende geschweifte Klammer gefolgt von einem Fragezeichen.
greedy_ha_regex = re.compile(r'(Ha){3,5}')
mo1 = greedy_ha_regex.search('HaHaHaHaHa')
mo1.group()
'HaHaHaHaHa'
non_greedy_ha_regex = re.compile(r'(Ha){3,5}?')
mo2 = non_greedy_ha_regex.search('HaHaHaHaHa')
mo2.group()
'HaHaHa'
Melden Sie sich an, um dieses Quiz zu beantworten und Ihren Lernfortschritt zu verfolgen
_ anstelle von +? nach dem Quantifizierer (z. B. _?, +?, {3,5}?)Die findall()-Methode
Die Methode findall() gibt die Strings aller Übereinstimmungen im durchsuchten String zurück.
phone_num_regex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') # hat keine Gruppen
phone_num_regex.findall('Handy: 415-555-9999 Büro: 212-555-0000')
['415-555-9999', '212-555-0000']
Eigene Zeichenklassen erstellen
Sie können Ihre eigene Zeichenklasse mit eckigen Klammern definieren. Zum Beispiel gleicht die Zeichenklasse [aeiouAEIOU] jeden Vokal ab, sowohl klein als auch groß.
vowel_regex = re.compile(r'[aeiouAEIOU]')
vowel_regex.findall('Robocop isst Babynahrung. BABY NAHRUNG.')
['o', 'o', 'o', 'e', 'a', 'a', 'o', 'o', 'A', 'O', 'O']
Sie können auch Buchstaben- oder Zahlenbereiche einschließen, indem Sie einen Bindestrich verwenden. Zum Beispiel gleicht die Zeichenklasse [a-zA-Z0-9] alle Kleinbuchstaben, Großbuchstaben und Zahlen ab.
Indem Sie ein Zirkumflexzeichen (^) direkt nach der öffnenden Klammer der Zeichenklasse platzieren, können Sie eine negative Zeichenklasse erstellen, die alle Zeichen abgleicht, die nicht in der Zeichenklasse enthalten sind:
consonant_regex = re.compile(r'[^aeiouAEIOU]')
consonant_regex.findall('Robocop isst Babynahrung. BABY NAHRUNG.')
['R', 'b', 'c', 'p', ' ', 't', 's', ' ', 'b', 'b', 'y', ' ', 'f', 'd', '.', ' ', 'B', 'B', 'Y', ' ', 'F', 'D', '.']
Die Zeichen Caret und Dollar
Sie können das Zirkumflexsymbol
^auch am Anfang eines Regex verwenden, um anzuzeigen, dass eine Übereinstimmung am Anfang des durchsuchten Textes erfolgen muss.Ebenso können Sie ein Dollarzeichen
$am Ende des Regex platzieren, um anzuzeigen, dass der String mit diesem Regex-Muster enden muss.Und Sie können
^und$zusammen verwenden, um anzuzeigen, dass der gesamte String mit dem Regex übereinstimmen muss.
Der reguläre Ausdrucksstring r'^Hello' gleicht Strings ab, die mit ‘Hello’ beginnen:
begins_with_hello = re.compile(r'^Hello')
begins_with_hello.search('Hello world!')
<_sre.SRE_Match object; span=(0, 5), match='Hello'>
begins_with_hello.search('He said hello.') is None
True
Der reguläre Ausdrucksstring r'\d\$' gleicht Strings ab, die mit einer numerischen Zeichenfolge von 0 bis 9 enden:
whole_string_is_num = re.compile(r'^\d+$')
whole_string_is_num.search('1234567890')
<_sre.SRE_Match object; span=(0, 10), match='1234567890'>
whole_string_is_num.search('12345xyz67890') is None
True
whole_string_is_num.search('12 34567890') is None
True
Das Wildcard-Zeichen
Das Zeichen . (oder Punkt) in einem regulären Ausdruck gleicht jedes Zeichen außer einem Zeilenumbruch ab:
at_regex = re.compile(r'.at')
at_regex.findall('Die Katze auf der Matte saß auf der flachen Matte.')
['cat', 'hat', 'sat', 'lat', 'mat']
Alles mit Dot-Star abgleichen
name_regex = re.compile(r'First Name: (.*) Last Name: (.*)')
mo = name_regex.search('First Name: Al Last Name: Sweigart')
mo.group(1)
'Al'
mo.group(2)
'Sweigart'
Das .* verwendet den gierigen Modus: Es versucht immer, so viel Text wie möglich abzugleichen. Um beliebigen Text nicht-gierig abzugleichen, verwenden Sie den Punkt, Stern und das Fragezeichen (.*?). Das Fragezeichen weist Python an, nicht-gierig abzugleichen:
non_greedy_regex = re.compile(r'<.*?>')
mo = non_greedy_regex.search('<To serve man> for dinner.>')
mo.group()
'<To serve man>'
greedy_regex = re.compile(r'<.*>')
mo = greedy_regex.search('<To serve man> for dinner.>')
mo.group()
'<To serve man> for dinner.>'
Zeilenumbrüche mit dem Punkt-Zeichen abgleichen
Der Punkt-Stern gleicht alles außer einem Zeilenumbruch ab. Indem Sie re.DOTALL als zweites Argument an re.compile() übergeben, können Sie das Punktzeichen dazu bringen, alle Zeichen abzugleichen, einschließlich des Zeilenumbruchzeichens:
no_newline_regex = re.compile('.*')
no_newline_regex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group()
'Serve the public trust.'
newline_regex = re.compile('.*', re.DOTALL)
newline_regex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group()
'Serve the public trust.\nProtect the innocent.\nUphold the law.'
Groß-/Kleinschreibung ignorierendes Matching
Um Ihr Regex fallunempfindlich zu machen, können Sie re.IGNORECASE oder re.I als zweites Argument an re.compile() übergeben:
robocop = re.compile(r'robocop', re.I)
robocop.search('Robocop ist teils Mensch, teils Maschine, ganz Cop.').group()
'Robocop'
robocop.search('ROBOCOP schützt die Unschuldigen.').group()
'ROBOCOP'
robocop.search('Al, warum spricht dein Programmierbuch so viel über robocop?').group()
'robocop'
Strings mit der sub()-Methode ersetzen
Die Methode sub() für Regex-Objekte wird mit zwei Argumenten aufgerufen:
- Das erste Argument ist ein String, der alle Übereinstimmungen ersetzen soll.
- Das zweite ist der String für den regulären Ausdruck.
Die Methode sub() gibt einen String mit den angewendeten Ersetzungen zurück:
names_regex = re.compile(r'Agent \w+')
names_regex.sub('ZENSIERT', 'Agent Alice gab die geheimen Dokumente an Agent Bob.')
'ZENSIERT gab die geheimen Dokumente an ZENSIERT.'
Melden Sie sich an, um dieses Quiz zu beantworten und Ihren Lernfortschritt zu verfolgen
sub()?Verwaltung komplexer Regexes
Um der Funktion re.compile() mitzuteilen, dass Leerzeichen und Kommentare innerhalb des regulären Ausdrucksstrings ignoriert werden sollen, kann der “Verbose-Modus” aktiviert werden, indem die Variable re.VERBOSE als zweites Argument an re.compile() übergeben wird.
Anstatt eines schwer lesbaren regulären Ausdrucks wie diesem:
phone_regex = re.compile(r'((\d{3}|\(\d{3}\))?(\s|-|\.)?\d{3}(\s|-|\.)\d{4}(\s*(ext|x|ext.)\s*\d{2,5})?)')
können Sie den regulären Ausdruck über mehrere Zeilen mit Kommentaren wie folgt verteilen:
phone_regex = re.compile(r'''(
(\d{3}|\(\d{3}\))? # Vorwahl
(\s|-|\.)? # Trennzeichen
\d{3} # erste 3 Ziffern
(\s|-|\.) # Trennzeichen
\d{4} # letzte 4 Ziffern
(\s*(ext|x|ext.)\s*\d{2,5})? # Durchwahl
)''', re.VERBOSE)
Melden Sie sich an, um dieses Quiz zu beantworten und Ihren Lernfortschritt zu verfolgen
re.VERBOSE, wenn es an re.compile() übergeben wird?