2015-05-13 12 views

Odpowiedz

10

Aby upewnić się, że cały ciąg pasuje, trzeba użyć \Zend-of-string anchor:

def fullmatch(regex, string, flags=0): 
    """Emulate python-3.4 re.fullmatch().""" 
    return re.match("(?:" + regex + r")\Z", string, flags=flags) 

\A kotwica nie jest konieczne, ponieważ re.match() już zakotwicza dopasowanie do początku łańcucha.

+1

Można również użyć '$', aby dopasować do końca linii. – gaborous

+1

@gaborous: To może się przydać, ponieważ 'regex' może zawierać modyfikator' (? M) ', a następnie mniej niż cały ciąg znaków mógłby się równać. –

1

Tu jest mój backport, który ma co najmniej jeden problem (dzięki tim-pietzcker) ale nie wymaga rekompilacji regexes:

import re 

def fullmatch(regex, string, flags=0): 
    """Emulate python-3.4 re.fullmatch().""" 
    m = re.match(regex, string, flags=flags) 
    if m and m.span()[1] == len(string): 
     return m 

A oto kilka testowe przypadki potwierdzające powyższą emulacji-funkcji.

def compare_expansion(regex, s, template): 
    m1 = re.fullmatch(regex, s) 
    s1 = m1.expand(template) if m1 else '<NO-MATCH>' 
    m2 = fullmatch(regex, s) 
    s2 = m2.expand(template) if m2 else '<NO-MATCH>' 
    if s1 != s2: 
     raise AssertionError("\n PY-3: '%s' \n PY-2: '%s' " % (s1, s2)) 

compare_expansion('.*', 'foo', r'A') 
compare_expansion('(.*)', 'foo', r'A_\1') 
compare_expansion('(.*)', 'foo', r'A_\g<0>') 

compare_expansion('a.*', 'afoo&', r'A') 
compare_expansion('a(\w*)', 'afoo&', r'A_\1') 
compare_expansion('a(\w*)', 'afoo&', r'A_\g<0>') 

## But this fails! 
compare_expansion(".*?", "Hello", '\g<0>') 
AssertionError: 
    PY-3: 'A_Hello' 
    PY-2: '<NO-MATCH>' 
+1

Nie powiedzie się to z leniwymi kwantyfikatorami: 're.fullmatch (". *? "," Hello ")' zwraca 'Brak', gdzie powinien zwrócić dopasowanie. –

+0

Dzięki za szybki połów! – ankostis

Powiązane problemy