2015-04-22 11 views
14

Z dokumentacji, to jest jasne, że:Dlaczego warto skorzystać z re.match(), kiedy re.search() może zrobić to samo?

  • match() -> zastosować wzór mecz na początku łańcucha
  • search() -> przeszukać ciąg i powrócić pierwszy mecz

I search z '^' i bez flagi re.M będzie działać tak samo jak match.

Dlaczego więc python ma match()? Czy to nie jest zbyteczne? Czy są jakieś korzyści związane z wydajnością w utrzymywaniu match() w python?

+1

Jest to wygoda dla wspólnego wzoru i sprawia, że ​​cel jest wyraźniejszy. – Barmar

+0

Zobacz [to pytanie] (https://stackoverflow.com/questions/12803709/re-match-vs-re-search-performance-difference) na testy wydajności. 're.search' może być czasami szybsze. – miradulo

+1

możliwy duplikat: http://stackoverflow.com/questions/180986/what-is-the-difference-between-pythons-re-search-and-re-match –

Odpowiedz

4

„dlaczego” pytania trudno odpowiedzieć. W rzeczywistości, można zdefiniować funkcję re.match() tak:

def match(pattern, string, flags): 
    return re.search(r"\A(?:" + pattern + ")", string, flags) 

(bo \A zawsze mecze na początku łańcucha, niezależnie od re.M flagi status').

Tak więc re.match jest przydatnym skrótem, ale nie jest to absolutnie konieczne. Jest to szczególnie mylące dla programistów Java, którzy mają Pattern.matches(), który zakotwicza wyszukiwanie do początku i kończy ciągu (co jest prawdopodobnie bardziej powszechnym przypadkiem użycia niż tylko zakotwiczeniem do początku).

Jest inna dla match i search metod regex sprzeciwia, chociaż, jak Eric podkreślił.

+1

_ "można zdefiniować funkcję" _ Nie, nie możesz.To dopasowanie daje inny wynik, gdy jest używane z argumentem "pos" (zakładając, że przesłałeś go gdzie to konieczne) – Eric

+0

@Eric: Funkcje * na poziomie modułu * nie mają argumentu "pos". Działają tylko metody obiektu regex (dlatego wspomniałem twoją odpowiedź w ostatnim wierszu). –

11

pos argumentem zachowuje się inaczej w ważnych sposobów:

>>> s = "a ab abc abcd" 
>>> re.compile('a').match(s, pos=2) 
<_sre.SRE_Match object; span=(2, 3), match='a'> 
>>> re.compile('^a').search(s, pos=2) 
None 

match umożliwia napisać tokenizera, i upewnić się, że znaki nie są pomijane. search nie ma możliwości powiedzenia "zacznij od najwcześniejszej dozwolonej postaci".

Przykład użycia meczu zerwać łańcuch bez przerw:

def tokenize(s, patt): 
    at = 0 
    while at < len(s): 
     m = patt.match(s, pos=at) 
     if not m: 
      raise ValueError("Did not expect character at location {}".format(at)) 
     at = m.end() 
     yield m 
+0

Może to dotyczyć funkcji pattern.match() i pattern.search(). Dla funkcji rematch (patn, string, flags = 0), która nie ma argumentów "pos", to wyjaśnienie nie jest dobre. Jak wskazał @Tim, może być użytecznym skrótem, który nie potrzebuje programisty do używania '^'. – elephant

+0

@mhr: Byłoby niespójne, gdyby na poziomie modułu brakowało metody dopasowania, ale – Eric

Powiązane problemy