2010-05-10 16 views
18

Chcę dopasować ostatnie wystąpienie prostego wzorca w ciągu znaków, np.Znajdź ostatni mecz z pythonem regularnym wyrażeniem

list = re.findall(r"\w+ AAAA \w+", "foo bar AAAA foo2 AAAA bar2") 
print "last match: ", list[len(list)-1] 

jednak, jeśli ciąg jest bardzo długo, generowana jest ogromna lista meczów. Czy istnieje bardziej bezpośredni sposób dopasowania drugiego wystąpienia "AAAA", czy też powinienem użyć tego obejścia?

+6

Inną opcją może być odwrócenie ciągu znaków ('mystr [:: - 1]') i wyszukanie pierwszego wystąpienia odwrotności wzoru. – ChristopheD

+2

@ ChristopheD, Gross! Jedynie rzecz trudniejsza do zrozumienia niż regex jest odwrotna. – mlissner

Odpowiedz

24

można użyć $ że oznacza koniec charakteru linia:

>>> s = """foo bar AAAA 
foo2 AAAA bar2""" 
>>> re.findall(r"\w+ AAAA \w+$", s) 
['foo2 AAAA bar2'] 

Należy również pamiętać, że list jest zła nazwa zmiennej, ponieważ cienie wbudowany typ. Aby uzyskać dostęp do ostatniego elementu listy można po prostu użyć [-1] index:

>>> lst = [2, 3, 4] 
>>> lst[-1] 
4 
+0

co, jeśli natknąłem się na ciąg wieloliniowy? – SDD

+1

@SDD: nadal będzie dobrze działać – SilentGhost

+3

Nie będzie działać dla łańcucha wejściowego w następujący sposób: "foo bar AAAA foo2 AAAA bar2 bar3". Oczywiście nie wiemy, czy taki przypadek jest możliwy, nie mamy wystarczających informacji. – tzot

22

Można uniknąć budowania listy tylko przez Iterowanie nad wszystkie mecze i utrzymanie Ostatni mecz:

for match in re.finditer(r"\w+ AAAA \w+", "foo bar AAAA foo2 AAAA bar2"): 
    pass 

Po to, match zawiera ostatnie dopasowanie i działa dla wszystkich kombinacji wzorca i szukanego ciągu. Najpierw możesz ustawić match na None, ponieważ jeśli nie będzie pasować, match nie będzie ustawiona na żadną wartość.

+0

Jest to bardzo przydatne w wielu przypadkach. Zwykle chcesz zastąpić wszystkie wystąpienia wzorca, a następnie niestandardowo przetworzyć ostatnią część łańcucha wejściowego. –

Powiązane problemy