2016-11-10 2 views
0

Ich bin mit regulären Ausdrücken sehr vertraut und brauche Hilfe beim Auffinden des richtigen regulären Ausdrucks.Regulärer Ausdruck, der mit dem optionalen folgenden Text übereinstimmt

Ich habe eine Textdatei der Form:

apple 4 
bananas 5 
bananas 5 7 
apple 3 
apple 6 
bananas 3 
bananas 4 5 
apple 3 
bananas 9 

ich für einen regulären Ausdruck suchen, die das letzte Vorkommen "bananas.*" nach jedem "apple.*" übereinstimmen, dass es für jeden "apple.*" im Auge behalten nicht sein kann "bananas.*". Die Regex sollte mit folgenden übereinstimmen:

bananas 5 7 
bananas 4 5 
bananas 9 

Vielen Dank im Voraus. Ich mache das in Python, wenn das hilft.

+1

Was würde helfen, zu zeigen, was Sie versucht haben und uns zu sagen, in welches Problem Sie geraten sind? – MooingRawr

+1

Auch, was hat rekursives etwas damit zu tun? –

+0

Die rekursive Natur kommt in diesem Sinne ähnlich einem Push-Pop-Stack. –

Antwort

1

Es ist eigentlich möglich mit regulären Ausdrücken:

^apple.+[\n\r] 
(?:(bananas.*)[\n\r]?)+ 

a demo on regex101.com Siehe, beachten Sie die verschiedenen Modifikatoren und Verwendung Gruppe 1 von jedem Spiel.


Als Full Python Code:

import re 

string = """ 
apple 4 
bananas 5 
bananas 5 7 
apple 3 
apple 6 
bananas 3 
bananas 4 5 
apple 3 
bananas 9 
""" 

rx = re.compile(r""" 
     ^apple.+[\n\r] 
     (?:(bananas.*)[\n\r]?)+ 
     """, re.MULTILINE | re.VERBOSE) 

bananas = [m.group(1) for m in rx.finditer(string)] 
print(bananas) 

Siehe a demo on ideone.com.

0

Es gibt nichts, das rekursiv sein müsste. Hier ist ein Muster, das funktioniert:

>>> fruit_lit = """apple 4 
bananas 5 
bananas 5 7 
apple 3 
apple 6 
bananas 3 
bananas 4 5 
apple 3 
bananas 9""" 

>>> re.findall(r'apple\s*\d*\s*\n(?:bananas\s*(?:\d+\s*)+\n)*(bananas(?:\s*\d+)+)\s*', fruit_list) 
['bananas 5 7', 'bananas 4 5', 'bananas 9'] 

Und wie viele der Kommentare erwähnen, regex ist vielleicht nicht der beste Weg, um zu bekommen, was Sie versuchen, zu finden. Iterieren über jede Zeile und Testen line.starswith('apple') dann line.startswith('banana') für jede nachfolgende Zeile könnte ein besserer Weg sein.