Domanda

Qual è la differenza tra le funzioni search () e match () nelle modulo Python re ?

Ho letto la documentazione (< a href = "http://docs.python.org/2/library/re.html?highlight=matching%20searching#search-vs-match" rel = "noreferrer"> documentazione corrente ), ma I sembra non ricordarlo mai. Continuo a cercare e riapprenderlo. Spero che qualcuno risponderà chiaramente con esempi in modo che (forse) mi si attacchi alla testa. O almeno avrò un posto migliore per tornare con la mia domanda e ci vorrà meno tempo per riapprenderla.

È stato utile?

Soluzione

re.match è ancorato all'inizio della stringa. Non ha nulla a che fare con le nuove righe, quindi non è lo stesso che usare ^ nel modello.

Come dice la re.match documentazione :

  

Se zero o più caratteri in    inizio della stringa corrisponde al modello di espressione regolare, restituisce a   istanza MatchObject corrispondente.   Restituisce Nessuno se la stringa no   abbinare il modello; si noti che questo è   diverso da una corrispondenza di lunghezza zero.

     

Nota: se si desidera individuare una corrispondenza   dovunque nella stringa, usa search ()   invece.

re.search cerca nell'intera stringa, come la documentazione dice :

  

Scansiona la stringa cercando un   posizione in cui l'espressione regolare   il modello produce una corrispondenza e restituisce a   istanza MatchObject corrispondente.   Restituisce Nessuno se nessuna posizione in   la stringa corrisponde al modello; nota che   questo è diverso dal trovare un   corrispondenza di lunghezza zero ad un certo punto nel   stringa.

Quindi, se devi abbinare all'inizio della stringa o per far corrispondere l'intera stringa usa match . È più veloce. Altrimenti usa cerca .

La documentazione ha una sezione specifica per match vs. cerca che copre anche stringhe multilinea:

  

Python offre due primitive diverse   operazioni basate su regolari   espressioni: match verifica una corrispondenza    solo all'inizio della stringa,   mentre cerca verifica una corrispondenza    ovunque nella stringa (ecco cosa   Perl lo fa di default).

     

Nota che corrisponde può differire da cerca   anche quando si utilizza un'espressione regolare   che inizia con '^' : '^' corrisponde solo a   all'inizio della stringa o dentro   Anche la modalità MULTILINE immediatamente   seguendo una nuova riga. La " match "   l'operazione ha esito solo se il modello   corrispondenze all'inizio della stringa   indipendentemente dalla modalità o all'inizio   posizione data dal pos opzionale   argomento indipendentemente dal fatto che a   newline lo precede.

Ora, basta parlare. È ora di vedere qualche codice di esempio:

# 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

Altri suggerimenti

cerca ? trova qualcosa in qualsiasi punto della stringa e restituisce un oggetto match.

match ? trova qualcosa inizio della stringa e restituisce un oggetto match.

re.search cerca es per il pattern in tutta la stringa , mentre re.match fa non cercare il modello; in caso contrario, non ha altra scelta che abbinarlo all'inizio della stringa.

è possibile fare riferimento all'esempio seguente per comprendere il funzionamento di re.match e re.search

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

re.match non restituirà nessuno, ma re.search restituirà abc.

La differenza è che re.match () induce in errore chiunque sia abituato a Perl , grep o sed corrispondenza delle espressioni regolari e re.search () no. :-)

Più seriamente, Come osserva John D. Cook , re.match ( ) " si comporta come se ogni modello abbia ^ anteposto. " In altre parole, re.match ('pattern') è uguale a re.search ('^ pattern') . Quindi fissa il lato sinistro di un motivo. Ma anche non fissa il lato destro di un pattern: che richiede ancora un $ terminante.

Detto francamente quanto sopra, penso che re.match () dovrebbe essere deprecato. Sarei interessato a sapere i motivi per cui dovrebbe essere mantenuto.

  La corrispondenza

è molto più veloce della ricerca, quindi invece di eseguire regex.search (" word ") puoi eseguire regex.match ((. *?) word (. *?)) e ottenere tonnellate di prestazioni se lo sei lavorando con milioni di campioni.

Questo commento di @ivan_bilan sotto il risposta accettata sopra mi ha fatto pensare se tale hack stia effettivamente accelerando qualcosa, quindi scopriamo quante tonnellate di prestazioni otterrai davvero.

Ho preparato la seguente suite di test:

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)

Ho effettuato 10 misurazioni (1 M, 2 M, ..., 10 M parole) che mi hanno dato il seguente diagramma:

 match vs. search regex speedtest line plot

Le linee risultanti sono sorprendentemente (in realtà non così sorprendentemente) dritte. E la funzione cerca è (leggermente) più veloce data questa combinazione di pattern specifica. La morale di questo test: Evita di ottimizzare il tuo codice.

re.match tenta di far corrispondere un modello all'inizio della stringa . re.search tenta di abbinare il modello in tutta la stringa fino a quando non trova una corrispondenza.

Molto più breve:

  • cerca scansiona l'intera stringa.

  • corrisponde Fa solo l'inizio della stringa.

Il seguente Ex lo dice:

>>> a = "123abc"
>>> re.match("[a-z]+",a)
None
>>> re.search("[a-z]+",a)
abc
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top