it-swarm.com.de

Was ist der Unterschied zwischen re.search und re.match?

Was ist der Unterschied zwischen den Funktionen search() und match() im Modul Python re ?

Ich habe die Dokumentation ( aktuelle Dokumentation ) gelesen, aber ich scheine mich nie daran zu erinnern. Ich muss es immer wieder nachschlagen und neu lernen. Ich hoffe, dass jemand es klar mit Beispielen beantwortet, so dass (vielleicht) es in meinem Kopf stecken bleibt. Oder zumindest habe ich einen besseren Ort, um mit meiner Frage zurückzukehren, und es wird weniger Zeit dauern, um es erneut zu lernen.

451
Daryl Spitzer

re.match Ist am Anfang der Zeichenfolge verankert. Das hat nichts mit Zeilenumbrüchen zu tun, es ist also nicht dasselbe wie die Verwendung von ^ Im Muster.

Wie in der Dokumentation zu re.match heißt es:

Wenn null oder mehr Zeichen amAnfang der Zeichenfolgemit dem Muster des regulären Ausdrucks übereinstimmen, geben Sie eine entsprechende Instanz MatchObject zurück. Gibt None zurück, wenn der String nicht mit dem Muster übereinstimmt. Beachten Sie, dass sich dies von einer Übereinstimmung mit der Länge Null unterscheidet.

Hinweis: Wenn Sie eine Übereinstimmung in einer Zeichenfolge suchen möchten, verwenden Sie stattdessen search().

re.search Durchsucht den gesamten String, wie in der Dokumentation steht :

Durchsuche den Stringund suche nach einer Stelle, an der das Muster des regulären Ausdrucks eine Übereinstimmung ergibt, und gib eine entsprechende MatchObject -Instanz zurück. Gibt None zurück, wenn keine Position in der Zeichenfolge mit dem Muster übereinstimmt. Beachten Sie, dass sich dies von der Suche nach einer Übereinstimmung mit der Länge Null an einem bestimmten Punkt in der Zeichenfolge unterscheidet.

Wenn Sie also am Anfang der Zeichenfolge oder mit der gesamten Zeichenfolge übereinstimmen müssen, verwenden Sie match. Es ist schneller. Ansonsten verwenden Sie search.

Die Dokumentation enthält einen spezifischen Abschnitt für match vs. search , der auch mehrzeilige Zeichenfolgen abdeckt:

Python bietet zwei verschiedene primitive Operationen an, die auf regulären Ausdrücken basieren: match sucht nach einer Übereinstimmungnur am Anfangdes Strings, während search nach einer Übereinstimmung suchtanywherein der Zeichenfolge (dies ist die Standardeinstellung von Perl).

Beachten Sie, dass match von search abweichen kann, auch wenn ein regulärer Ausdruck verwendet wird, der mit '^' Beginnt: '^' Stimmt nur am Anfang der Zeichenfolge oder in MULTILINE -Modus auch unmittelbar nach einem Zeilenumbruch. Die Operation "match" ist erfolgreich nur wenn das Muster amstartder Zeichenfolge übereinstimmt ​​unabhängig vom Modus oder an der von der angegebenen Startposition optionales Argument pos, unabhängig davon, ob eine neue Zeile davor steht.

Jetzt genug geredet. Es ist Zeit, einen Beispielcode zu sehen:

# example code:
string_with_newlines = """something
someotherthing"""

import re

print re.match('some', string_with_newlines) # matches
print re.match('someother', 
               string_with_newlines) # won't match
print re.match('^someother', string_with_newlines, 
               re.MULTILINE) # also won't match
print re.search('someother', 
                string_with_newlines) # finds something
print re.search('^someother', string_with_newlines, 
                re.MULTILINE) # also finds something

m = re.compile('thing$', re.MULTILINE)

print m.match(string_with_newlines) # no match
print m.match(string_with_newlines, pos=4) # matches
print m.search(string_with_newlines, 
               re.MULTILINE) # also matches
454
nosklo

search ⇒ Finde irgendwo in der Zeichenkette etwas und gib ein Übereinstimmungsobjekt zurück.

match ⇒ Suchen Sie etwas am Anfang der Zeichenfolge und geben Sie ein Übereinstimmungsobjekt zurück.

re.searchSuche es für das Muster in der gesamten Zeichenfolge, während re.match durchsucht das Muster nicht ; Wenn dies nicht der Fall ist, hat es keine andere Wahl als match it am Anfang der Zeichenfolge.

46
xilun

match ist viel schneller als search. Anstatt also regex.search ("Word") auszuführen, können Sie regex.match ((. *?) Word (. *?)) ausführen und eine Menge Leistung erzielen, wenn Sie mit Millionen von Benutzern arbeiten Proben.

Dieser Kommentar von @ivan_bilan unter der oben akzeptierten Antwort brachte mich zu der Überlegung, ob ein solcher Hack tatsächlich etwas beschleunigt. Lassen Sie uns also herausfinden, wie viele Tonnen Leistung vorhanden sind Sie werden wirklich gewinnen.

Ich habe folgende Testsuite vorbereitet:

import random
import re
import string
import time

LENGTH = 10
LIST_SIZE = 1000000

def generate_Word():
    Word = [random.choice(string.ascii_lowercase) for _ in range(LENGTH)]
    Word = ''.join(Word)
    return Word

wordlist = [generate_Word() for _ in range(LIST_SIZE)]

start = time.time()
[re.search('python', Word) for Word in wordlist]
print('search:', time.time() - start)

start = time.time()
[re.match('(.*?)python(.*?)', Word) for Word in wordlist]
print('match:', time.time() - start)

Ich machte 10 Messungen (1M, 2M, ..., 10M Wörter), die mir die folgende Darstellung gaben:

match vs. search regex speedtest line plot

Die resultierenden Linien sind überraschenderweise (eigentlich nicht überraschenderweise) gerade. Und die Funktion search ist bei dieser bestimmten Musterkombination (geringfügig) schneller . Die Moral dieses Tests: Vermeiden Sie eine Überoptimierung Ihres Codes.

30
Jeyekomon

Der Unterschied ist, re.match() irreführt jeden, der daran gewöhnt ist Perl, grep oder sed Übereinstimmung mit regulären Ausdrücken, und re.search() nicht. :-)

Nüchterner, Wie John D. Cook bemerkt , re.match() "verhält sich so, als hätte jedes Muster vorangestellt." Mit anderen Worten, re.match('pattern') entspricht re.search('^pattern'). So verankert es die linke Seite eines Musters. Aber es verankert nicht die rechte Seite eines Musters: erfordert immer noch einen abschließenden $.

Ehrlich gesagt denke ich, dass re.match() veraltet sein sollte. Mich würde interessieren, warum das so ist.

25
CODE-REaD

Anhand des folgenden Beispiels können Sie die Funktionsweise von re.match Und re.search nachvollziehen

a = "123abc"
t = re.match("[a-z]+",a)
t = re.search("[a-z]+",a)

re.match Gibt none zurück, aber re.search Gibt abc zurück.

25
ldR

re.match versucht ein Muster zu finden am Anfang der Zeichenkette. re.search versucht, dem Muster zu entsprechen in der gesamten Zeichenfolge bis eine Übereinstimmung gefunden wird.

14
cschol

Viel kürzer:

  • search durchsucht den gesamten String.

  • match Führt nur den Stringanfang aus.

Folgende Ex sagt es:

>>> a = "123abc"
>>> re.match("[a-z]+",a)
None
>>> re.search("[a-z]+",a)
abc
1
U10-Forward