Erweitertes Python – Reguläre Ausdrücke

Was ist der Nutzen?

Schauen wir uns ein Beispiel an.

In einer Textdatei werden einige Marktpositionsinformationen gespeichert. Das Format ist wie folgt

Python3 高级开发工程师 上海互教教育科技有限公司上海-浦东新区2万/月02-18满员
测试开发工程师(C++/python) 上海墨鹍数码科技有限公司上海-浦东新区2.5万/每月02-18未满员
Python3 开发工程师 上海德拓信息技术股份有限公司上海-徐汇区1.3万/每月02-18剩余11人
测试开发工程师(Python) 赫里普(上海)信息科技有限公司上海-浦东新区1.1万/每月02-18剩余5人
Python高级开发工程师 上海行动教育科技股份有限公司上海-闵行区2.8万/月02-18剩余255人
python开发工程师 上海优似腾软件开发有限公司上海-浦东新区2.5万/每月02-18满员

Jetzt müssen wir ein Programm schreiben, um die Gehälter aller Positionen aus diesen Texten zu ermitteln.

ist es, solche Ergebnisse zu erzielen

2
2.5
1.3
1.1
2.8
2.5

Wie es geht?
 

Dies ist eine typische String-Verarbeitung.

Wenn wir die Regeln hier analysieren, können wir feststellen, dass es Schlüsselwörter  万/月 oder  gibt万/每月

Schreiben Sie den folgenden Code

content = '''
Python3 高级开发工程师 上海互教教育科技有限公司上海-浦东新区2万/月02-18满员
测试开发工程师(C++/python) 上海墨鹍数码科技有限公司上海-浦东新区2.5万/每月02-18未满员
Python3 开发工程师 上海德拓信息技术股份有限公司上海-徐汇区1.3万/每月02-18剩余11人
测试开发工程师(Python) 赫里普(上海)信息科技有限公司上海-浦东新区1.1万/每月02-18剩余5人
Python高级开发工程师 上海行动教育科技股份有限公司上海-闵行区2.8万/月02-18剩余255人
python开发工程师 上海优似腾软件开发有限公司上海-浦东新区2.5万/每月02-18满员
'''

# 将文本内容按行放入列表
lines = content.splitlines()
for line in lines:
    # 查找'万/月' 在 字符串中什么地方
    pos2 = line.find('万/月')
    if pos2 < 0:
        # 查找'万/每月' 在 字符串中什么地方
        pos2 = line.find('万/每月')
        # 都找不到
        if pos2 < 0: 
            continue

    # 执行到这里,说明可以找到薪资关键字
    # 接下来分析 薪资 数字的起始位置
    # 方法是 找到 pos2 前面薪资数字开始的位置
    idx = pos2-1

    # 只要是数字或者小数点,就继续往前面找
    while line[idx].isdigit() or line[idx]=='.':
        idx -= 1

    # 现在 idx 指向 薪资数字前面的那个字,
    # 所以薪资开始的 索引 就是 idx+1
    pos1 = idx + 1

    print(line[pos1:pos2])

 Gibt es dafür einen einfacheren Weg? 从字符串中搜索出某种特征的子串

Die Lösung stellen wir Ihnen heute vor  正则表达式 .


Wenn wir reguläre Ausdrücke verwenden, kann der Code so aussehen

content = '''
Python3 高级开发工程师 上海互教教育科技有限公司上海-浦东新区2万/月02-18满员
测试开发工程师(C++/python) 上海墨鹍数码科技有限公司上海-浦东新区2.5万/每月02-18未满员
Python3 开发工程师 上海德拓信息技术股份有限公司上海-徐汇区1.3万/每月02-18剩余11人
测试开发工程师(Python) 赫里普(上海)信息科技有限公司上海-浦东新区1.1万/每月02-18剩余5人
Python高级开发工程师 上海行动教育科技股份有限公司上海-闵行区2.8万/月02-18剩余255人
python开发工程师 上海优似腾软件开发有限公司上海-浦东新区2.5万/每月02-18满员
'''

import re
for one in  re.findall(r'([\d.]+)万/每{0,1}月', content):
    print(one)

Führen Sie es aus und sehen Sie, das Ergebnis ist das gleiche.

Aber der Code ist viel einfacher.

Ein regulärer Ausdruck ist eine Syntax, mit der die Merkmale der Zeichenfolge beschrieben werden, nach der Sie suchen möchten.

Hier wird ein regulärer Ausdruck angegeben

re.findall(r'([\d.]+)万/每{0,1}月', content)

([\d.]+)万/每{0,1}月 , eine reguläre Ausdruckszeichenfolge, die die Merkmale der Suchteilzeichenfolge angibt.

Warum schreibst du das? Wir werden es später vorstellen.

Die Funktion findall gibt alle passenden Teilzeichenfolgen in einer Liste zurück.

Wie aus dem obigen Beispiel ersichtlich ist, ist der Schlüssel zur Verwendung regulärer Ausdrücke  如何写出正确的表达式语法 : .

Klicken Sie hier, um die Beschreibung in der offiziellen Python-Dokumentation anzuzeigen  . Spezifische Nutzungsdetails einschließlich Syntax sind darin enthalten.

Dieses Tutorial führt Sie in einige gängige reguläre Ausdruckssyntax ein.

Online-Verifizierung

Wie kann überprüft werden, ob der von Ihnen geschriebene Ausdruck korrekt mit der zu durchsuchenden Zeichenfolge übereinstimmt?

Sie können diese URL besuchen:  regex101: Regex erstellen, testen und debuggen

Geben Sie den Suchtext und den Suchausdruck gemäß der schematischen Abbildung unten ein, um zu sehen, ob Ihr Ausdruck korrekt mit der Zeichenfolge übereinstimmen kann.

Die oben genannte Verifizierungswebsite befindet sich im Ausland. Wenn Sie nicht darauf zugreifen können, versuchen Sie es mit dieser inländischen Website zur Verifizierung regulärer Ausdrücke

gemeinsame Grammatik

In regulären Ausdrücken geschriebene gewöhnliche Zeichen bedeuten: Passen Sie ihnen direkt zu.

Wenn Sie beispielsweise in Ihrem Text unten alle Tests finden möchten, ist der reguläre Ausdruck sehr einfach. Geben Sie einfach test direkt ein.

Folgendermaßen:

Das Gleiche gilt für chinesische Schriftzeichen. Um chinesische Schriftzeichen zu finden, schreiben Sie sie einfach direkt in den regulären Ausdruck.


Es gibt jedoch einige Sonderzeichen, der Begriff wird Metazeichen (Metazeichen) genannt .

Sie erscheinen in der Zeichenfolge des regulären Ausdrucks, nicht um direkt mit ihnen übereinzustimmen, sondern um eine besondere Bedeutung auszudrücken.

Zu diesen speziellen Metazeichen gehören die folgenden:

. * + ? \ [ ] ^ $ { } | ( )

Lassen Sie uns ihre Bedeutungen separat vorstellen:

Punkt – entspricht allen Zeichen

. bedeutet,  换行符 jedes  Zeichen außer zu finden. 单个

Sie möchten beispielsweise alle Farben aus dem Text unten auswählen.

苹果是绿色的
橙子是橙色的
香蕉是黄色的
乌鸦是黑色的

Das heißt, alle   Wörter zu finden, die mit dem vorherigen Zeichen enden und dieses enthalten.

Sie können reguläre Ausdrücke wie diesen schreiben  . .色

Der Punkt stellt ein beliebiges Zeichen dar. Beachten Sie, dass es sich um ein Zeichen handelt.

.色 Sie zu kombinieren bedeutet, nach einem beliebigen Zeichen zu suchen, gefolgt vom Wort „Farbe“, und die beiden Zeichen zu kombinieren

Überprüfen Sie es, wie in der Abbildung unten gezeigt

Solange der Ausdruck korrekt ist, kann er wie folgt in Python-Code geschrieben werden

content = '''苹果是绿色的
橙子是橙色的
香蕉是黄色的
乌鸦是黑色的'''

import re
p = re.compile(r'.色')
for one in  p.findall(content):
    print(one)

Das Ergebnis der Operation ist wie folgt

绿色
橙色
黄色
黑色

Sternchen – Übereinstimmung beliebig oft wiederholen

* Gibt an, dass der vorhergehende Unterausdruck beliebig oft, einschließlich 0 Mal, gefunden wurde.

Sie möchten beispielsweise den Zeichenfolgeninhalt nach dem Komma in jeder Zeile, einschließlich des Kommas selbst, aus dem folgenden Text auswählen. Beachten Sie, dass es sich bei den Kommas hier um chinesische Kommas handelt.

苹果,是绿色的
橙子,是橙色的
香蕉,是黄色的
乌鸦,是黑色的
猴子,

Sie können reguläre Ausdrücke wie diesen schreiben  ,.* .

  • Unmittelbar nach dem . bedeutet, dass jedes Zeichen beliebig oft vorkommen kann, sodass der gesamte Ausdruck alle Zeichen nach dem Komma bedeutet, einschließlich des Kommas

Überprüfen Sie es, wie in der Abbildung unten gezeigt

Insbesondere in der letzten Zeile gibt es nach dem Affenkomma keine weiteren Zeichen, aber * bedeutet, dass es 0-mal übereinstimmen kann, sodass der Ausdruck auch gültig ist.

Solange der Ausdruck korrekt ist, kann er wie folgt in Python-Code geschrieben werden

content = '''苹果,是绿色的
橙子,是橙色的
香蕉,是黄色的
乌鸦,是黑色的
猴子,'''

import re
p = re.compile(r',.*')
for one in  p.findall(content):
    print(one)

Das Ergebnis der Operation ist wie folgt

,是绿色的
,是橙色的
,是黄色的
,是黑色的
,

Beachten Sie, dass .* in regulären Ausdrücken sehr häufig vorkommt und bedeutet, dass jedes Zeichen beliebig oft gefunden werden muss.

Natürlich müssen diesem * keine Punkte vorangestellt werden , es können auch andere Zeichen sein, wie z.B

Pluszeichen – Übereinstimmung mehrmals wiederholen

bedeutet, dass der vorhergehende Unterausdruck ein- oder mehrmals mit Ausnahme von 0-mal übereinstimmt .

Im obigen Beispiel müssen Sie beispielsweise den Zeichenfolgeninhalt nach dem Komma in jeder Zeile aus dem Text auswählen, einschließlich des Kommas selbst.

Fügen Sie jedoch eine Bedingung hinzu. Wenn nach dem Komma kein Inhalt vorhanden ist, wählen Sie ihn nicht aus.

Wenn beispielsweise im folgenden Text nach dem Komma in der letzten Zeile kein Inhalt steht, wählen Sie ihn nicht aus.

苹果,是绿色的
橙子,是橙色的
香蕉,是黄色的
乌鸦,是黑色的
猴子,

Sie können reguläre Ausdrücke wie diesen schreiben  ,.+ .

Überprüfen Sie es, wie in der Abbildung unten gezeigt

In der letzten Zeile gibt es nach dem Affenkomma keine weiteren Zeichen und + bedeutet mindestens eine Übereinstimmung, sodass in der letzten Zeile keine Teilzeichenfolge ausgewählt wurde.

Fragezeichen – passt 0-1 Mal

? Gibt an, dass der vorhergehende Unterausdruck 0 oder 1 Mal übereinstimmt.

Im obigen Beispiel möchten Sie beispielsweise in jeder Zeile des Textes, einschließlich des Kommas selbst, ein Zeichen nach dem Komma auswählen.

苹果,绿色的
橙子,橙色的
香蕉,黄色的
乌鸦,黑色的
猴子,

Sie können reguläre Ausdrücke wie diesen schreiben  . ,.?

Überprüfen Sie es, wie in der Abbildung unten gezeigt

In der letzten Zeile gibt es nach dem Affenkomma keine weiteren Zeichen, aber ? bedeutet 1- oder 0-malige Übereinstimmung, sodass in der letzten Zeile auch ein Kommazeichen ausgewählt wird.

Geschweifte Klammern – entsprechen der angegebenen Häufigkeit

Geschweifte Klammern zeigen an, dass das vorangehende Zeichen übereinstimmt  指定的次数 .

Zum Beispiel der folgende Text

红彤彤,绿油油,黑乎乎,绿油油油油

Der Ausdruck  油{3} bedeutet, dass aufeinanderfolgende Ölzeichen dreimal abgeglichen werden

Der Ausdruck  油{3,4} bedeutet, dass aufeinanderfolgende Ölzeichen mindestens dreimal und höchstens viermal übereinstimmen

Es kann nur mit Letzterem übereinstimmen, wie unten gezeigt:

Gierig und nicht gierig

Wir möchten alle HTML-Tags in der folgenden Zeichenfolge extrahieren:

source = '<html><head><title>Title</title>'

Holen Sie sich eine Liste wie diese

['<html>', '<head>', '<title>', '</title>']

Es ist leicht, sich die Verwendung regulärer Ausdrücke vorzustellen <.*>

Schreiben Sie den folgenden Code

source = '<html><head><title>Title</title>'

import re
p = re.compile(r'<.*>')

print(p.findall(source))

Aber das laufende Ergebnis ist

['<html><head><title>Title</title>']

was ist passiert? Es stellt sich heraus, dass in regulären Ausdrücken „*“, „+“ und „?“ alle gierig sind. Wenn Sie sie verwenden, werden sie so weit wie möglich übereinstimmen.

Daher  wurde das Sternchen in (das eine beliebige Anzahl von Wiederholungen angibt) mit dem e am Ende der Zeichenfolge <.*> abgeglichen . </title> 

Um dieses Problem zu lösen, müssen Sie den nicht gierigen Modus verwenden, dh ihn nach dem Sternchen hinzufügen  ? , und es sieht so aus <.*?>

Code geändert in

source = '<html><head><title>Title</title>'

import re
# 注意多出的问号
p = re.compile(r'<.*?>')

print(p.findall(source))

Führen Sie es erneut aus und es sollte funktionieren

Metazeichen maskieren

Backslashes werden in regulären Ausdrücken auf unterschiedliche Weise verwendet. \ 

Beispielsweise möchten wir nach allen Zeichenfolgen suchen, die im folgenden Text vor einem Punkt stehen, einschließlich des Punkts selbst

苹果.是绿色的
橙子.是橙色的
香蕉.是黄色的

Wenn wir reguläre Ausdrücke wie diesen schreiben  .*. , müssen Sie schlau sein und feststellen, dass etwas nicht stimmt.

Da der Punkt ein Metazeichen ist , erscheint er direkt im regulären Ausdruck, was bedeutet, dass er mit einem einzelnen Zeichen übereinstimmt und nicht die Bedeutung des Zeichens selbst darstellen kann.

Wie es geht?

Wenn der Inhalt, den wir durchsuchen möchten, Metazeichen enthält, können wir diese mit Backslashes maskieren .

Hier verwenden wir Ausdrücke wie diese: .*\.

Das Python-Programm sieht beispielsweise wie folgt aus

content = '''苹果.是绿色的
橙子.是橙色的
香蕉.是黄色的'''

import re
p = re.compile(r'.*\.')
for one in  p.findall(content):
    print(one)

Das Ergebnis der Operation ist wie folgt

苹果.
橙子.
香蕉.

einem bestimmten Zeichentyp entsprechen

Eine Anzahl von Zeichen gefolgt von einem Backslash gibt an, dass  某种类型 ein einzelnes Zeichen übereinstimmen muss.

Zum Beispiel

\d entspricht jedem numerischen Zeichen zwischen 0 und 9, äquivalent zum Ausdruck [0-9]

\D entspricht jedem Zeichen, das keine Zahl zwischen 0 und 9 ist, äquivalent zum Ausdruck [^0-9]

\s entspricht jedem Leerzeichen, einschließlich Leerzeichen, Tabulatoren, Zeilenumbrüchen usw., äquivalent zum Ausdruck [\t\n\r\f\v]

\S entspricht jedem nicht leeren Zeichen, äquivalent zum Ausdruck [^ \t\n\r\f\v]

\w entspricht jedem Textzeichen, einschließlich Groß- und Kleinbuchstaben, Zahlen und Unterstrichen, was dem Ausdruck [a-zA-Z0-9_] entspricht.

Standardmäßig werden auch Unicode-Textzeichen berücksichtigt. Bei Angabe von ASCII-Code-Tags werden nur ASCII-Buchstaben berücksichtigt.

\W entspricht jedem nicht-literalen Zeichen, das dem Ausdruck [^a-zA-Z0-9_] entspricht.

Backslashes können auch in eckigen Klammern verwendet werden, z. B. [\s,.], um Folgendes zu finden: ein beliebiges Leerzeichen, ein Komma oder einen Punkt

eckige Klammern – entspricht einem von mehreren Zeichen

Die eckigen Klammern geben an, dass es mit einem der angegebenen Zeichen übereinstimmt.

Zum Beispiel

[abc] Kann mit jedem Zeichen in a, b oder c übereinstimmen. Entspricht [a-c]  .

[a-c] A – in der Mitte gibt einen Bereich von a bis c an.

Wenn Sie alle Kleinbuchstaben abgleichen möchten, können Sie verwenden [a-z]

Einige Metazeichen verlieren in eckigen Klammern ihre Magie und werden zu normalen Zeichen.

Zum Beispiel

[akm.] passt zu  a k m . jedem Zeichen in

Hier  . in den Klammern bedeutet es nicht mehr, irgendein Zeichen zu finden, sondern  . dieses Zeichen


Wenn es in eckigen Klammern verwendet wird  ^ , bezeichnet es   die Zeichenmenge innerhalb der eckigen Klammern.

Zum Beispiel

content = 'a1b2c3d4e5'

import re
p = re.compile(r'[^\d]' )
for one in  p.findall(content):
    print(one)

[^\d] Zeigt an, dass nicht numerische Zeichen ausgewählt werden

Die Ausgabe ist:

a
b
c
d
e

Start-, Endposition und Single-Line-, Multi-Line-Modus

^ Gibt die Position des übereinstimmenden Texts an. 开头 

Reguläre Ausdrücke können gesetzt werden  单行模式 und 多行模式

Wenn ja  单行模式 , gibt es  整个文本 die Startposition des Spiels an.

Wenn ja  多行模式 , gibt es  文本每行 die Startposition des Spiels an.

Im folgenden Text gibt beispielsweise die Zahl oben in jeder Zeile die Nummer der Frucht und die letzte Zahl den Preis an

001-苹果价格-60,
002-橙子价格-70,
003-香蕉价格-80,

Wenn wir alle Fruchtzahlen extrahieren möchten, verwenden Sie einen regulären Ausdruck wie diesen ^\d+

Der obige reguläre Ausdruck, der im Python-Programm verwendet wird, lautet wie folgt

content = '''001-苹果价格-60
002-橙子价格-70
003-香蕉价格-80'''

import re
p = re.compile(r'^\d+', re.M)
for one in  p.findall(content):
    print(one)

Beachten Sie, dass der zweite Parameter re.M der Kompilierung die Verwendung des Mehrzeilenmodus angibt.

Das Ergebnis der Operation ist wie folgt

001
002
003

Wenn der zweite Parameter re.M der Kompilierung entfernt wird, sind die laufenden Ergebnisse wie folgt

001

Es gibt nur die erste Zeile.

Denn im einzeiligen Modus stimmt ^ nur mit dem Anfang des gesamten Textes überein.


$ Gibt  结尾 die Position des übereinstimmenden Texts an.

Wenn ja  单行模式 , gibt es  整个文本 die Endposition des Spiels an.

Wenn ja , gibt es die Endposition des Spiels an. 多行模式  文本每行 

Im folgenden Text gibt beispielsweise die Zahl oben in jeder Zeile die Nummer der Frucht und die letzte Zahl den Preis an

001-苹果价格-60,
002-橙子价格-70,
003-香蕉价格-80,

Wenn wir alle Fruchtzahlen extrahieren möchten, verwenden Sie einen regulären Ausdruck wie diesen \d+$

entsprechenden Code

content = '''001-苹果价格-60
002-橙子价格-70
003-香蕉价格-80'''

import re
p = re.compile(r'\d+$', re.MULTILINE)
for one in  p.findall(content):
    print(one)

Beachten Sie, dass der zweite Parameter der Kompilierung, re.MULTILINE, die Verwendung des Mehrzeilenmodus angibt.

Das Ergebnis der Operation ist wie folgt

60
70
80

Wenn der zweite Parameter re.MULTILINE der Kompilierung entfernt wird, lauten die laufenden Ergebnisse wie folgt

80

Es gibt nur die letzte Zeile.

Denn im einzeiligen Modus stimmt $ nur mit der Endposition des gesamten Textes überein.

vertikaler Balken – entspricht einem der

Ein vertikaler Balken bedeutet, dass einer von ihnen übereinstimmt.

Zum Beispiel,

Insbesondere ist zu beachten, dass vertikale Linien in regulären Ausdrücken die niedrigste Priorität haben, was bedeutet, dass die durch vertikale Linien getrennten Teile ein Ganzes bilden

Es bedeutet zum Beispiel, mit is  oder  übereinzustimmen  , 绿色|橙  绿色

statt  oder  绿色绿橙

Klammern - Gruppierung

Die Klammern werden als Gruppenauswahl des regulären Ausdrucks bezeichnet.

 Es dient dazu, den mit dem regulären Ausdruck übereinstimmenden Inhalt  其中的某些部分 als eine bestimmte Gruppe zu markieren.

多个 Wir können Gruppen im regulären Ausdruck  markieren

Warum gibt es einen Gruppenbegriff? Weil wir oft Informationen über bestimmte Teile des übereinstimmenden Inhalts extrahieren müssen.

Zuvor hatten wir aus dem folgenden Text ein Beispiel, das auch die Zeichenfolgen vor den Kommas in jeder Zeile auswählt .包括逗号本身 

苹果,苹果是绿色的
橙子,橙子是橙色的
香蕉,香蕉是黄色的

Sie können reguläre Ausdrücke wie diesen schreiben  ^.*, .

Aber was wäre, wenn wir darum bitten würden,  keine Kommas einzufügen  ?

Natürlich kann man so nicht direkt schreiben ^.*

Da es sich bei dem letzten Komma um die Funktion handelt, können Sie das vor dem Komma stehende Komma nicht finden, wenn Sie es entfernen.

Aber wenn man Kommas in den regulären Ausdruck einfügt, schließt das auch Kommas ein.

Die Lösung des Problems besteht darin, Gruppenselektoren zu verwenden: Klammern .

Wir schreiben so  ^(.*), , das Ergebnis ist wie folgt

Sie können feststellen, dass wir den Teil, der aus dem gesamten Ausdruck extrahiert werden soll, in Klammern setzen, sodass die Namen der Früchte allein in der Gruppe stehen.

Der entsprechende Python-Code lautet wie folgt

content = '''苹果,苹果是绿色的
橙子,橙子是橙色的
香蕉,香蕉是黄色的'''

import re
p = re.compile(r'^(.*),', re.MULTILINE)
for one in  p.findall(content):
    print(one)

Die Gruppierung kann auch mehrfach verwendet werden.

Beispielsweise möchten wir aus dem folgenden Text den Namen jeder Person und die entsprechende Mobiltelefonnummer extrahieren

张三,手机号码15945678901
李四,手机号码13945677701
王二,手机号码13845666901

Ein regulärer Ausdruck wie dieser kann verwendet werden ^(.+),.+(\d{11})

Der folgende Code kann geschrieben werden

content = '''张三,手机号码15945678901
李四,手机号码13945677701
王二,手机号码13845666901'''

import re
p = re.compile(r'^(.+),.+(\d{11})', re.MULTILINE)
for one in  p.findall(content):
    print(one)

Wenn es mehrere Gruppen gibt, können wir  (?P<分组名>...) dieses Format verwenden, um jede Gruppe zu benennen.

Dies hat den Vorteil, dass nachfolgende Codes den Inhalt jeder Gruppe bequemer extrahieren können

Zum Beispiel

content = '''张三,手机号码15945678901
李四,手机号码13945677701
王二,手机号码13845666901'''

import re
p = re.compile(r'^(?P<name>.+),.+(?P<phone>\d{11})', re.MULTILINE)
for match in  p.finditer(content):
    print(match.group('name'))
    print(match.group('phone'))

Lassen Sie den Punkt mit dem Zeilenumbruch übereinstimmen

Wie ich bereits sagte,   ja  不匹配换行符 , aber manchmal ist die Merkmalszeichenfolge zeilenübergreifend, um beispielsweise alle Berufsbezeichnungen im folgenden Text zu finden

<div class="el">
        <p class="t1">           
            <span>
                <a>Python开发工程师</a>
            </span>
        </p>
        <span class="t2">南京</span>
        <span class="t3">1.5-2万/月</span>
</div>
<div class="el">
        <p class="t1">
            <span>
                <a>java开发工程师</a>
            </span>
		</p>
        <span class="t2">苏州</span>
        <span class="t3">1.5-2/月</span>
</div>

Wenn Sie den Ausdruck direkt verwenden,  class=\"t1\">.*?<a>(.*?)</a> werden Sie feststellen, dass er nicht übereinstimmt, da  zwischen t1 und  <a> zwei Leerzeilen stehen .

Zu diesem Zeitpunkt benötigen Sie   Parameter 点也匹配换行符 , die Sie verwenden können DOTALL

so was

content = '''
<div class="el">
        <p class="t1">           
            <span>
                <a>Python开发工程师</a>
            </span>
        </p>
        <span class="t2">南京</span>
        <span class="t3">1.5-2万/月</span>
</div>
<div class="el">
        <p class="t1">
            <span>
                <a>java开发工程师</a>
            </span>
		</p>
        <span class="t2">苏州</span>
        <span class="t3">1.5-2/月</span>
</div>
'''

import re
p = re.compile(r'class=\"t1\">.*?<a>(.*?)</a>', re.DOTALL)
for one in  p.findall(content):
    print(one)

zurück zum Anfangsbeispiel

Schauen wir uns mit dem oben genannten Wissen das Beispiel am Anfang dieses Artikels an

Finden Sie die Gehälter für alle Positionen im folgenden Text.

Python3 高级开发工程师 上海互教教育科技有限公司上海-浦东新区2万/月02-18满员
测试开发工程师(C++/python) 上海墨鹍数码科技有限公司上海-浦东新区2.5万/每月02-18未满员
Python3 开发工程师 上海德拓信息技术股份有限公司上海-徐汇区1.3万/每月02-18剩余11人
测试开发工程师(Python) 赫里普(上海)信息科技有限公司上海-浦东新区1.1万/每月02-18剩余5人

Der Ausdruck, den wir verwenden, ist ([\d.]+)万/每{0,1}月

Warum schreibst du es so?

[\d.]+ Bedeutet, mehrere Vorkommen einer Zahl oder eines Punktes abzugleichen. Dies würde Zahlen wie die folgenden abgleichen: 3 33 33,33

万/每{0,1}月 Wenn dies nicht der Fall ist, wird es mit anderen Zahlen übereinstimmen, z. B. 3 in Python3.

Unter anderem  bedeutet dieser Teil, dass  jeder Charakter 0 oder 1 Mal im Spiel vorkommen kann. 每{0,1}月 每月

Gibt es eine andere Möglichkeit, dies auszudrücken  每{0,1}月 ?

Es kann auch verwendet werden, da das Fragezeichen bedeutet, dass das vorherige Zeichen 0 oder 1 Mal übereinstimmt 每?月 

Schnur abschneiden

Die Methoden des String-Objekts eignen sich nur für die einfache String-Aufteilung. Manchmal ist ein flexibleres Schneiden der Saiten erforderlich. split 

Beispielsweise müssen wir den Namen des Generals aus der folgenden Zeichenfolge extrahieren.

names = '关羽; 张飞, 赵云,马超, 黄忠  李逵'

Wir haben festgestellt, dass einige dieser Namen durch Semikolons, andere durch Kommas und andere durch Leerzeichen getrennt sind und dass sich um das Trennzeichen eine unbegrenzte Anzahl von Leerzeichen befindet

Zu diesem Zeitpunkt können Sie die Split-Methode im regulären Ausdruck verwenden:

import re

names = '关羽; 张飞, 赵云,   马超, 黄忠  李逵'

namelist = re.split(r'[;,\s]\s*', names)
print(namelist)

Der reguläre Ausdruck  [;,\s]\s* gibt an, dass das Trennzeichen ein Semikolon, ein Komma oder ein Leerzeichen sein kann und dass um das Symbol eine unbegrenzte Anzahl von Leerzeichen stehen kann.

Saitenersatz

Übereinstimmungsmusterersetzung

Die Methoden des String-Objekts  replace eignen sich nur für einfache Ersetzungen. Manchmal benötigen Sie eine flexiblere Zeichenfolgenersetzung.

Beispielsweise müssen wir alle Links im folgenden Text finden, die  mit /avxxxxxx/ beginnen  /av , gefolgt von einer Reihe von Zahlen und der Zeichenfolge dieses Musters.

Diese Zeichenfolgen werden dann alle durch ersetzt  /cn345677/ .

names = '''

下面是这学期要学习的课程:

<a href='https://www.bilibili.com/video/av66771949/?p=1' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是牛顿第2运动定律

<a href='https://www.bilibili.com/video/av46349552/?p=125' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是毕达哥拉斯公式

<a href='https://www.bilibili.com/video/av90571967/?p=33' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是切割磁力线
'''

Der zu ersetzende Inhalt ist nicht festgelegt, daher kann die Ersetzungsmethode der Zeichenfolge nicht verwendet werden.

Zu diesem Zeitpunkt können Sie die Sub-Methode im regulären Ausdruck verwenden:

import re

names = '''

下面是这学期要学习的课程:

<a href='https://www.bilibili.com/video/av66771949/?p=1' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是牛顿第2运动定律

<a href='https://www.bilibili.com/video/av46349552/?p=125' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是毕达哥拉斯公式

<a href='https://www.bilibili.com/video/av90571967/?p=33' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是切割磁力线
'''

newStr = re.sub(r'/av\d+?/', '/cn345677/' , names)
print(newStr)

Die Untermethode dient auch zum Ersetzen von Zeichenfolgen, der ersetzte Inhalt verwendet jedoch reguläre Ausdrücke, um alle Zeichenfolgen darzustellen, die den Merkmalen entsprechen.

 Hier ist zum Beispiel der reguläre Ausdruck des  ersten Parameters , was bedeutet, dass eine  Zeichenfolge  , die mit beginnt, gefolgt von einer Zahlenfolge und  endet mit, ersetzt werden muss. /av\d+?//av/

Der zweite Parameter, hier ist  '/cn345677/' diese Zeichenfolge, die angibt, was ersetzt werden soll.

Der dritte Parameter ist die Quellzeichenfolge.

Geben Sie eine Ersetzungsfunktion an

Im vorherigen Beispiel haben wir zum Ersetzen eine feste Zeichenfolge verwendet  /cn345677/.

Wenn wir benötigen, dass der Inhalt nach dem Ersetzen beispielsweise die ursprüngliche Zahl + 6 ist,  ersetzen Sie ihn durch  . /av66771949/ /av66771955/

Für diese komplexere Ersetzung können wir den zweiten Parameter von sub  指定为一个函数 , den Rückgabewert der Funktion, als Zeichenfolge für die Ersetzung verwenden.

folgendermaßen

import re

names = '''

下面是这学期要学习的课程:

<a href='https://www.bilibili.com/video/av66771949/?p=1' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是牛顿第2运动定律

<a href='https://www.bilibili.com/video/av46349552/?p=125' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是毕达哥拉斯公式

<a href='https://www.bilibili.com/video/av90571967/?p=33' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是切割磁力线
'''

# 替换函数,参数是 Match对象
def subFunc(match):
    # Match对象 的 group(0) 返回的是整个匹配上的字符串, 
    src = match.group(0)
    
    # Match对象 的 group(1) 返回的是第一个group分组的内容
    number = int(match.group(1)) + 6
    dest = f'/av{number}/'

    print(f'{src} 替换为 {dest}')

    # 返回值就是最终替换的字符串
    return dest

newStr = re.sub(r'/av(\d+?)/', subFunc , names)
print(newStr)

Rufen Sie die Zeichenfolge wie folgt in der Gruppe ab

match.group(0) # 获取整个匹配字符串
match.group(1) # 获取第1个组内字符串
match.group(2) # 获取第2个组内字符串

In Versionen nach Python 3.6 kann die Schreibmethode auch prägnanter sein und Indizes wie eine Liste direkt verwenden, wie folgt

match[0]
match[1]
match[2]

Im Beispiel oben:

Wenn die re.sub-Funktion des regulären Ausdrucks ausgeführt wird,  lautet die übereinstimmende Teilzeichenfolge: 每发现一个

  • Instanziieren Sie ein Match-Objekt

    Dieses Match-Objekt enthält Informationen zu dieser Übereinstimmung, z. B.: Was ist die gesamte Zeichenfolge, was ist der übereinstimmende Teil der Zeichenfolge und was sind die darin enthaltenen Gruppenzeichenfolgen?

  • Rufen Sie das zweite Parameterobjekt der Unterfunktion auf und führen Sie es aus, dh rufen Sie die Rückruffunktion subFunc auf

    Und übergeben Sie das gerade generierte Match-Objekt als Parameter an subFunc

Ich denke du magst

Origin blog.csdn.net/weixin_47649808/article/details/126325560
Empfohlen
Rangfolge