2017-11-21 5 views
2

Ich habe die folgenden Absätze:Wie passe ich Absätze mit einem bestimmten Muster an Regex an?

This is paragraph #1 
New-York, London, Paris, Berlin 
Some other text 
End of paragraph 

This is paragraph #2 
London, Paris 
End of paragraph 

This is paragraph #3 
New-York, Paris, Berlin 
Some other text 
End of paragraph 

This is paragraph #4 
End of paragraph 

This is paragraph #5 
Paris, Berlin 
Some other text 
End of paragraph 

Wie kann ich mit einem regulären Ausdruck, entsprechen die Absätze zum Beispiel enthalten, New-York (# 1 und # 3) oder London (# 1, # 2)? oder gar New York und Berlin (# 1, # 3)?

Ich habe eine Antwort in S.O gefunden.

How match a paragraph using regex

, die mir die Absätze (alle den Text zwischen zwei Leerzeilen) übereinstimmen können.

Aber ich kann nicht (meine Regex-Fähigkeiten sind ... begrenzt), wie die Absätze mit einem bestimmten Muster und nur diese Absätze übereinstimmen.

Vielen Dank im Voraus für Ihre Hilfe

NB: die Idee ist, die Antwort in der Editorial IOS App zu verwenden, um die Antworten zu falten das Muster nicht enthalten.

+0

Welche Programmiersprache verwenden Sie? Es könnte einfacher sein, die Absätze zuerst zu trennen (in leeren Zeilen) und dann nach "New-York" zu suchen. – Jan

+0

Welcher Geschmack von Regex? Python? Müssen Sie Regex in einer Zeile verwenden? Die Antwort, die Sie verknüpfen, teilt sich auf "\ n \ n". – kabanus

+0

@kabanus: Python – ThG

Antwort

2

Ich sehe, Sie könnten keinen Zugriff auf den Python-Code haben selbst wenn Sie das Muster in der Editorial iOS-App verwenden möchten.

Dann alles, was ich vorschlagen kann, ist das Muster wie

(?m)^(?=.*(?:\r?\n(?!\r?\n).*)*?\bNew-York\b)(?=.*(?:\r?\n(?!\r?\n).*)*?\bBerlin\b).*(?:\r?\n(?!\r?\n).*)* 

die regex demo See. Grundsätzlich passen wir nur vom Anfang der Zeile (^ mit (?m) Modifizierer), wir überprüfen, ob es New-York und Berlin als ganze Wörter (aufgrund der \b Wortgrenzen) irgendwo auf den Zeilen vor der ersten doppelten Zeilenumbruch und wenn vorhanden , match diese Zeilen.

Einzelheiten

  • (?m)^ - Anfang der Zeile
  • (?=.*(?:\r?\n(?!\r?\n).*)*?\bNew-York\b) - eine positive Vorschau, die sicherstellen, da ein ganzes Wort New-York überall nach 0+ Zeichen außer Zeilenumbruch Zeichen ist (.*) optional gefolgt von 0+ aufeinanderfolgenden Folgen von CRLF/LF Zeilenumbrüchen, gefolgt von einem weiteren CRLF/LF Zeilenumbrüche, gefolgt von dem Rest der Zeile
  • (?=.*(?:\r?\n(?!\r?\n).*)*?\bBerlin\b) - ein ganzes Wort Berlin irgendwo nach 0+ Zeichen außer Zeilenumbruch Zeichen (.*) optional gefolgt von 0+ aufeinanderfolgenden Folgen von CRLF/LF Zeilenumbrüche nicht gefolgt mit einem anderen CRLF/LF Zeilenumbrüche gefolgt mit dem Rest der Zeile
  • .* - passen Sie die
  • Linie
  • (?:\r?\n(?!\r?\n).*)* - entspricht 0+ aufeinanderfolgenden Vorkommen von:
    • \r?\n(?!\r?\n) - ein Zeilenumbruch (CRLF oder LF) nicht mit einem anderen CRLF oder LF gefolgt
    • .* - der Rest der Zeile.
1

der newer regex module Mit der leer Splits unterstützt:

import regex as re 

string = """ 
This is paragraph #1 
New-York, London, Paris, Berlin 
Some other text 
End of paragraph 

This is paragraph #2 
London, Paris 
End of paragraph 

This is paragraph #3 
New-York, Paris, Berlin 
Some other text 
End of paragraph 

This is paragraph #4 
End of paragraph 

This is paragraph #5 
Paris, Berlin 
Some other text 
End of paragraph 
""" 

rx = re.compile(r'^$', flags = re.MULTILINE | re.VERSION1) 

needle = 'New-York' 

interesting = [part 
    for part in rx.split(string) 
    if needle in part] 

print(interesting) 
# ['\nThis is paragraph #1\nNew-York, London, Paris, Berlin\nSome other text\nEnd of paragraph\n', '\nThis is paragraph #3\nNew-York, Paris, Berlin\nSome other text\nEnd of paragraph\n'] 
+0

1) Danke für Ihre Antwort 2) Ich habe es in Pythonista versucht (der gleiche Entwickler wie Editorial; BTW, Editorial kann Python-Skripte verwenden) und lief auf Probleme, weil - ich denke - es scheint nicht die neuere Regex zu unterstützen Modul 3) Ihre Antwort scheint zu bedeuten, dass es keine reine Regex-Lösung (PCRE) gibt. – ThG

0

Ich denke, Ihre konkreten Fall überhaupt keine regex erfordert:

[i for i,p in enumerate(mystr.split('\n\n')) if 'New-York' in p or 'London' in p] 

In Ihrem Fall in resultierenden:

[0, 1, 2] 

Offensichtlich ein and Zustand genauso einfach ist, oder negiert die if. enumerate wird nur verwendet, wenn Sie den Absatzindex haben möchten. Sie brauchen es nicht, wenn Sie den Absatz selbst möchten. Keine Notwendigkeit, die regex in jedem Fall zu erzwingen.

Verwandte Themen