Frage

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

Ich habe die Dokumentation lesen (< a href = "http://docs.python.org/2/library/re.html?highlight=matching%20searching#search-vs-match" rel = "noreferrer"> aktuelle Dokumentation ), aber ich nie scheint es zu merken. Ich muss immer wieder danach suchen und wieder lernen es. Ich hoffe, dass jemand es eindeutig mit Beispielen zu beantworten, so dass (vielleicht) es in meinem Kopf bleiben wird. Oder zumindest werde ich zu einem besseren Ort mit meiner Frage zurückkommen müssen, und es wird weniger Zeit in Anspruch nehmen, um es neu zu lernen.

War es hilfreich?

Lösung

re.match wird am Anfang des Strings verankert. Das hat nichts mit Zeilenumbrüchen zu tun, so ist es nicht die gleiche wie mit ^ im Muster.

Als re.match Dokumentation sagt:

  

Wenn null oder mehr Zeichen bei der    Anfang Zeichenfolge , um das Muster eines regulären Ausdrucks übereinstimmen, kehren ein   entsprechende MatchObject Instanz.   Rück None, wenn die Zeichenfolge nicht der Fall ist   entspricht das Muster; beachten Sie, dass dies   unterscheidet sich von einer Null-Länge übereinstimmen.

     

Hinweis: Wenn Sie möchten, um eine Übereinstimmung finden   überall in string, verwenden search()   statt.

re.search sucht die gesamte Zeichenfolge, wie die Dokumentation sagt :

  

Scan durch Zeichenfolge Suche nach einem   Ort, an dem der regulären Ausdruck   Muster erzeugt ein Spiel, und das Rück ein   entsprechende MatchObject Instanz.   Zurück None, wenn keine Position in der   String mit dem Muster; beachten Sie, dass   Dies unterscheidet sich von der Suche nach einem   an einem gewissen Punkt der Länge Null Spiel in der   String.

Wenn Sie also am Anfang der Zeichenfolge übereinstimmen, oder die gesamte Zeichenfolge Verwendung match anzupassen. Es ist schneller. Ansonsten search verwenden.

Die Dokumentation hat einen für match vs. search , die umfasst auch mehrzeilige Strings:

  

Python bietet zwei verschiedene primitive   Operationen auf der Grundlage regelmäßiger   Ausdrücke: match prüft, ob ein Spiel    nur am Anfang der Zeichenfolge,   während search prüft, ob ein Spiel    irgendwo in der Zeichenkette (das ist, was   Perl tut Standard).

     

Beachten Sie, dass match von search abweichen   selbst wenn ein regulären Ausdruck   mit '^' beginnen: '^' passt nur   zu Beginn des Strings, oder in   MULTILINE Modus sofort auch   nach einem Newline. Die „match“   Operation erfolgreich nur, wenn das Muster   Spiele in der Start der Zeichenfolge   unabhängig vom Modus oder am Start   Position durch den optionalen pos gegeben   Argument unabhängig davon, ob ein   Newline vorangeht.

Nun, genug geredet. Zeit, um einige Beispiel-Code, um 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

Andere Tipps

search ⇒ etwas irgendwo im String finden und ein Match-Objekt zurück.

match ⇒ etwas finden, an dem Anfang der Zeichenfolge und gibt ein Match-Objekt.

re.search Suche es für das Muster in der gesamten Zeichenfolge , während re.match tut nicht suchen das Muster; wenn dies nicht der Fall, es hat keine andere Wahl, als zu Spiel es am Anfang des Strings.

Sie können das unten stehende Beispiel beziehen sich die Arbeits von re.match und re.search verstehen

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

re.match kehrt keine, aber re.search wird abc zurück.

Der Unterschied ist, verleitet re.match() jemand daran gewöhnt, Perl grep oder sed reguläre Ausdrücke und re.search() nicht . : -)

nüchterner, Wie John D. Koch bemerkt , re.match() „verhält, als ob jedes Muster hat ^ vorangestellt.“ Mit anderen Worten entspricht re.match('pattern') re.search('^pattern'). So verankert sie eine linke Seite des Musters. Aber es auch nicht ein rechte Seite des Musters verankern. , die noch ein abschließendes $ erfordert

Ehrlich gesagt die oben angegebenen, denke ich re.match() veraltet werden sollte. Es würde mich interessieren Gründe zu wissen, es sollte beibehalten werden.

  

Spiel ist viel schneller als Suche, so dass anstelle regex.search zu tun ( „Wort“), können Sie Regex.Match tun ((. *?) Wort (. *?)) Und jede Menge Leistung gewinnen, wenn Sie arbeiten mit Millionen von Proben.

Dieser Kommentar von @ivan_bilan unter der akzeptierte Antwort oben hat mir denken, wenn eine solche Hack ist eigentlich alles bis zu beschleunigen, also lassen Sie uns herausfinden, wie viele Tonnen Leistung, die Sie wirklich gewinnen.

ich bereit, die folgende Testsuite:

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 habe 10 Messungen (1M, 2M, ..., 10M Worte), die mir die folgende Handlung gab:

 Spiel vs. Suche regex speedLinienDiagramm

Die resultierenden Linien sind überraschend (eigentlich gar nicht so überraschend) gerade. Und die search Funktion ist (leicht) schneller angesichts dieser spezifische Musterkombination. Die Moral dieser Test: Vermeiden Sie den Code overoptimizing

.

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

Viel kürzer:

  • search Scans Trog ganze Reihe.

  • match Hat erst am Anfang der Zeichenfolge.

Im Anschluss an Ex heißt es:

>>> a = "123abc"
>>> re.match("[a-z]+",a)
None
>>> re.search("[a-z]+",a)
abc
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top