Python - Regulärer Ausdruck zum Abgleichen eines mehrzeiligen Textblocks

Salman Mehmood 8 Oktober 2023
  1. Grund, Regex zu schreiben, um mehrzeilige Zeichenfolgen abzugleichen
  2. Mögliche Lösungen zum Abgleichen von mehrzeiligen Zeichenfolgen
Python - Regulärer Ausdruck zum Abgleichen eines mehrzeiligen Textblocks

Dieser Artikel beschreibt Möglichkeiten zum Suchen nach einem bestimmten Muster in mehrzeiligen Zeichenfolgen. Die Lösung umfasst mehrere Ansätze für bekannte und unbekannte Muster und erklärt, wie die übereinstimmenden Muster funktionieren.

Grund, Regex zu schreiben, um mehrzeilige Zeichenfolgen abzugleichen

Angenommen, wir haben den folgenden Textblock:

Any compiled body of information is known as a data set. Depending on the situation's specifics, this may be a database or a simple array.\n
\n
IBM first used the term "data set," which meant essentially the same thing as "file," to describe a collection of related records.

Aus dem oben angegebenen Textblock muss der Starttext gefunden werden, und der Text wird einige Zeilen darunter präsentiert. Es ist wichtig zu beachten, dass \n einen Zeilenumbruch symbolisiert und kein wörtlicher Text ist.

Zusammenfassend möchten wir Text über mehrere Zeilen finden und abgleichen, wobei alle leeren Zeilen ignoriert werden, die zwischen dem Text stehen können. Im Fall des oben erwähnten Textes sollte es die Zeile Jeder kompilierte Körper ... und die Zeile IBM hat den Begriff zuerst verwendet .... in einer einzigen Abfrage mit regulären Ausdrücken zurückgeben.

Mögliche Lösungen zum Abgleichen von mehrzeiligen Zeichenfolgen

Bevor die Lösungen für dieses spezielle Problem diskutiert werden, ist es wichtig, die verschiedenen Aspekte der Regex-API (regulärer Ausdruck) zu verstehen, insbesondere diejenigen, die in der Lösung häufig verwendet werden.

Beginnen wir also mit dem re.compile().

Python-Methode re.compile()

re. compile() kompiliert ein Regex-Muster in ein reguläres Ausdrucksobjekt, das wir für den Abgleich mit match(), search() und anderen beschriebenen Methoden verwenden können.

Ein Vorteil von re.compile() gegenüber unkompilierten Mustern ist die Wiederverwendbarkeit. Wir können den kompilierten Ausdruck mehrmals verwenden, anstatt für jedes nicht kompilierte Muster eine neue Zeichenfolge zu deklarieren.

import re as regex

pattern = regex.compile(".+World")
print(pattern.match("Hello World!"))
print(pattern.search("Hello World!"))

Ausgang:

<re.Match object; span=(0, 11), match='Hello World'>
<re.Match object; span=(0, 11), match='Hello World'>

Python-Methode re.search()

re. search() durchsucht einen String nach einer Übereinstimmung und gibt ein Match-Objekt zurück, wenn eines gefunden wird.
Wenn viele Übereinstimmungen vorhanden sind, geben wir die erste Instanz zurück.

Wir können es auch direkt ohne die Verwendung von re.compile() verwenden, anwendbar, wenn nur eine Abfrage erforderlich ist.

import re as regex

print(regex.search(".+World", "Hello World!"))

Ausgang:

<re.Match object; span=(0, 11), match='Hello World'>

Python-Methode re.finditer()

re.finditer() passt auf ein Muster innerhalb eines Strings und gibt einen Iterator zurück, der Match-Objekte für alle nicht überlappenden Übereinstimmungen liefert.

Wir können dann den Iterator verwenden, um über die Übereinstimmungen zu iterieren und die erforderlichen Operationen auszuführen; Die Übereinstimmungen werden so geordnet, wie sie gefunden wurden, von links nach rechts in der Zeichenfolge.

import re as regex

matches = regex.finditer(r"[aeoui]", "vowel letters")
for match in matches:
    print(match)

Ausgang:

<re.Match object; span=(1, 2), match='o'>
<re.Match object; span=(3, 4), match='e'>
<re.Match object; span=(7, 8), match='e'>
<re.Match object; span=(10, 11), match='e'>

Python-Methode re.findall()

re.findall() gibt eine Liste oder ein Tupel aller nicht überlappenden Übereinstimmungen eines Musters in einem String zurück. Ein String wird von links nach rechts gescannt. Und die Übereinstimmungen werden in der Reihenfolge zurückgegeben, in der sie entdeckt wurden.

import re as regex

# Find all capital words
string = ",,21312414.ABCDEFGw#########"
print(regex.findall(r"[A-Z]+", string))

Ausgang:

['ABCDEFG']

Python-Methode re.MULTILINE

Ein wesentlicher Vorteil von re.MULTILINE ist, dass ^ am Anfang jeder Zeile nach Mustern suchen kann, anstatt nur am Anfang des Strings.

Python-Regex-Symbole

Regex-Symbole können bei komplexer Verwendung schnell unübersichtlich werden. Nachfolgend finden Sie einige der Symbole, die in unseren Lösungen verwendet werden, um das zugrunde liegende Konzept dieser Symbole besser zu verstehen.

  • ^ behauptet die Position am Anfang einer Zeile
  • String entspricht wörtlich den (Groß-/Kleinschreibung beachtenden) Zeichen "String"
  • . stimmt mit allen Zeichen überein (mit Ausnahme von Symbolen, die für den Zeilenabschluss verwendet werden)
  • + stimmt so oft wie möglich mit dem zuvor gegebenen Token überein.
  • \n entspricht einem Zeilenumbruchzeichen
  • \r entspricht einem (CR) Wagenrücklaufzeichen
  • ? stimmt zwischen 0-1 Mal mit dem vorherigen Token überein
  • +? zwischen 1 und unendlich mal mit dem vorherigen Token übereinstimmt, so wenig wie möglich.
  • a-z entspricht einem einzelnen Zeichen im Bereich zwischen a und z (Groß-/Kleinschreibung beachten)

Verwenden Sie re.compile(), um einen mehrzeiligen Textblock in Python abzugleichen

Lassen Sie uns die Verwendung verschiedener Muster verstehen.

Muster 1: Verwenden Sie re.search() für bekannte Muster

Beispielcode:

import re as regex

multiline_string = "Regular\nExpression"
print(regex.search(r"^Expression", multiline_string, regex.MULTILINE))

Ausgang:

<re.Match object; span=(8, 18), match='Expression'>

Der obige Ausdruck behauptet zuerst seine Position am Anfang der Zeile (aufgrund von ^) und sucht dann nach den genauen Vorkommen von "Expression".

Die Verwendung des MULTILINE-Flags stellt sicher, dass jede Zeile auf Vorkommen von "Expression" überprüft wird, anstatt nur die erste Zeile.

Muster 2: Verwenden Sie re.search() für Unbekanntes Muster

Beispielcode:

import re as regex

data = """Any compiled body of information is known as a data set. Depending on the situation's specifics, this may be a database or a simple array.\n
\n
IBM first used the term "data set," which meant essentially the same thing as "file," to describe a collection of related records.
"""

result = regex.compile(r"^(.+)(?:\n|\r\n)+((?:(?:\n|\r\n?).+)+)", regex.MULTILINE)

print(result.search(data)[0].replace("\n", ""))

Ausgang:

Any compiled body of information is known as a data set. Depending on the situation's specifics, this may be a database or a simple array.IBM first used the term "data set," which meant essentially the same thing as "file," to describe a collection of related records.

Der Regex-Ausdruck kann zur besseren Lesbarkeit in kleinere Teile zerlegt und vereinfacht werden:

In der ersten Erfassungsgruppe (.+) wird jedes Zeichen in der Zeile abgeglichen (mit Ausnahme von Symbolen, die Zeilenabschlüssen entsprechen); Dieser Vorgang wird so oft wie möglich durchgeführt.

Danach werden in der nicht einfangenden Gruppe (?:\n|\r\n) nur ein Zeilenabschlusszeichen oder ein Zeilenabschlusszeichen und ein Wagenrücklauf so oft wie möglich abgeglichen.

Die zweite einfangende Gruppe ((?:(?:\n|\r\n?).+)+) besteht aus einer nicht einfangenden Gruppe (?:(?:\n|\r \n?).+)+ entweder ein Zeilenumbruchzeichen oder ein Zeilenumbruchzeichen und ein Wagenrücklauf werden maximal einmal abgeglichen.

Jedes Zeichen wird außerhalb der nicht einfangenden Gruppe abgeglichen, mit Ausnahme von Zeilenabschlusszeichen. Dieser Vorgang wird so oft wie möglich durchgeführt.

Muster 3: Verwenden Sie re.finditer() für Unbekanntes Muster

Beispielcode:

import re as regex

data = """Regex In Python

Regex is a feature available in all programming languages used to find patterns in text or data.
"""

query = regex.compile(r"^(.+?)\n([\a-z]+)", regex.MULTILINE)

for match in query.finditer(data):
    topic, content = match.groups()
    print("Topic:", topic)
    print("Content:", content)

Ausgang:

Topic: Regex In Python
Content: 
Regex is a feature available in all programming languages used to find patterns in text or data.

Der obige Ausdruck lässt sich wie folgt erklären:

In der ersten einfangenden Gruppe (.+?) werden alle Zeichen (bis auf die Zeilenabschlüsse wie bisher) so wenig wie möglich gematcht. Danach wird ein einzelnes Zeilenumbruchzeichen \n abgeglichen.

Nach dem Abgleich des Zeilenumbruchzeichens werden in der zweiten Erfassungsgruppe (\n[a-z ]+) die folgenden Operationen ausgeführt. Zuerst wird ein Zeilenumbruchzeichen gefunden, gefolgt von übereinstimmenden Zeichen zwischen a-z so oft wie möglich.

Verwenden Sie re.findall(), um einen mehrzeiligen Textblock in Python zu finden

Beispielcode:

import re as regex

data = """When working with regular expressions, the sub() function of the re library is an invaluable tool.

the subroutine looks over the string for the given pattern and applies the given replacement to all instances where it is found.
"""

query = regex.findall("([^\n\r]+)[\n\r]([a-z \n\r]+)", data)

for results in query:
    for result in results:
        print(result.replace("\n", ""))

Ausgang:

When working with regular expressions, the sub() function of the re library is an invaluable tool.
the subroutine looks over the string for the given pattern and applies the given replacement to all instances where it is found

Um die Regex-Erklärung besser zu verstehen, lassen Sie uns sie nach Gruppen aufschlüsseln und sehen, was jeder Teil tut.

In der ersten einfangenden Gruppe ([^\n\r]+) werden alle Zeichen mit Ausnahme eines Zeilenumbruchzeichens oder eines Wagenrücklaufzeichens so oft wie möglich abgeglichen.

Danach werden Übereinstimmungen hergestellt, wenn ein Zeichen entweder ein Wagenrücklauf oder ein Zeilenumbruch im Ausdruck [\n\r] ist.

In der zweiten Erfassungsgruppe ([a-z \n\r]+) werden Zeichen zwischen a-z oder einem Zeilenumbruch oder Wagenrücklauf so oft wie möglich abgeglichen.

Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn

Verwandter Artikel - Python Regex