2016-04-26 13 views
4

hier erfassen ist ein String:Wie beide Look-Ahead-Lookbehind regex python

str = "Academy \nADDITIONAL\nAwards and Recognition: Greek Man of the Year 2011 Stanford PanHellenic Community, American Delegate 2010 Global\nEngagement Summit, Honorary Speaker 2010 SELA Convention, Semi-Finalist 2010 Strauss Foundation Scholarship Program\nComputer Skills: Competency: MATLAB, MySQL/PHP, JavaScript, Objective-C, Git Proficiency: Adobe Creative Suite, Excel\n(highly advanced), PowerPoint, HTML5/CSS3\nLanguages: Fluent English, Advanced Spanish\n\x0c" 

Ich möchte von "addtional" auf "Sprachen" erfassen, so ich diese Regex schrieb:

regex = r'(?<=\n(ADDITIONAL|Additional)\n)[\s\S]+?(?=\n(Languages|LANGUAGES)\n*)' 

Es fängt jedoch nur alles zwischen ([\s\S]+). Es fängt nicht ADDTIONAL & Languages. Was fehlt mir hier?

+1

Der ganze Sinn von Lookahead und Lookbehind ist, dass sie ** nicht ** im Spiel enthalten sind. Es erfordert nur, dass sie in der Zeichenfolge vorhanden sind. – Barmar

+1

Verwenden Sie normale Erfassungsgruppen, wenn Sie sie einschließen möchten. – Barmar

+0

Oder verwenden Sie nicht erfassende Gruppen, wenn Sie sie einschließen möchten, aber nicht als separate Captures. – Barmar

Antwort

3

Ihre regex ist

regex = r'(?<=\n(ADDITIONAL|Additional)\n)[\s\S]+?(?=\n(Languages|LANGUAGES)\n*)' 

und die Zeichenfolge ist

Academy \nADDITIONAL\nAwards and Recognition: ... \nLanguages: 
        ^^       ^^ 
        ||       || 
Match Position:-(?<=\n(ADDITIONAL|Additional)\n)(?=\n(Languages|LANGUAGES)\n*) 

So [\s\S]+? den Inhalt zwischen diesen beiden Positionen enthalten außer ADDITIONAL und LANGUAGES.

Sie müssen nur die Startposition von ADDITIONAL und Endposition von LANGUAGES finden.Dies kann mit dem folgenden regex

(?=\n(ADDITIONAL|Additional)\n)([\s\S]+?)(?<=\n(Languages|LANGUAGES)\b) 

Weitere getan werden, wenn Sie [\s\S]+? wollen nur alle Inhalte zu erfassen, dann können Sie nicht Capturing Gruppen für Additional und Languages

(?=\n(?:ADDITIONAL|Additional)\n)[\s\S]+?(?<=\n(?:Languages|LANGUAGES)\b) 

Academy \nADDITIONAL\nAwards and Recognition: ... \nLanguages: 
     ^^             ^^ 
     ||             || 
(?=\n(ADDITIONAL|Additional)\n)    (?<=\n(Languages|LANGUAGES)) 

Python-Code verwenden

p = re.compile(r'(?=\n(?:ADDITIONAL|Additional)\n)[\s\S]+?(?<=\n(?:Languages|LANGUAGES)\b)', re.MULTILINE) 
test_str = "Academy \nADDITIONAL\nAwards and Recognition: Greek Man of the Year 2011 Stanford PanHellenic Community, American Delegate 2010 Global\nEngagement Summit, Honorary Speaker 2010 SELA Convention, Semi-Finalist 2010 Strauss Foundation Scholarship Program\nComputer Skills: Competency: MATLAB, MySQL/PHP, JavaScript, Objective-C, Git Proficiency: Adobe Creative Suite, Excel\n(highly advanced), PowerPoint, HTML5/CSS3\nLanguages: Fluent English, Advanced Spanish\n\x0c" 
print(re.findall(p, test_str)) 

Ideone Demo

+1

Beste Antwort unter allen! – Aaron

+0

@DDDrupal danke, aber ich werde sagen, dass dies hätte ohne Look arounds getan werden können – rock321987

0

Wenn Sie sie in das Match aufnehmen möchten, stellen Sie sie nicht in Lookarounds, da der Zweck darin besteht, auf umgebenden Text zu testen, ohne ihn in das Übereinstimmungsergebnis einzubeziehen. Verwenden Sie gewöhnliche nicht einfangende Gruppen, wenn Sie nur Abwechslung benötigen.

regex = r'\n(?:ADDITIONAL|Additional)\n[\s\S]+?\n(?:Languages|LANGUAGES)\n*' 

BTW, Ihre regexp erfordert Zeilenumbrüche um ADDITIONAL und Languages, aber es gibt keine in der Zeichenfolge.

+0

Hallo Barmar, danke für die Antwort. Ich habe deins versucht, aber es fängt nicht. Der Text, den ich versuche zu erreichen, ist: "Academy \ nAdditional \ nAuszeichnungen und Anerkennung: Griechischer Mann des Jahres 2011 Stanford PanHellenic Community, Amerikanischer Delegierter 2010 Global \ nVereinigungsgipfel, Ehrensprecher 2010 SELA Convention, Semi-Finalist 2010 Strauss Foundation Scholarship Program \ nComputer Skills: Kompetenz: MATLAB, MySQL/PHP, JavaScript, Objective-C, Git Kenntnisse: Adobe Creative Suite, Excel \ n (hochentwickelt), PowerPoint, HTML5/CSS3 \ nSprachen: Fließend Englisch, Fortgeschritten Spanisch \ n \ x0c " – Aaron

1

Es erfasst wird, aber es ist nicht Teil der Capture-Gruppe 0, weil der Gruppe 0
enthält nur die Spiel verbraucht, das heißt das Spiel, das die aktuelle
Position bewegt.

Behauptungen verschieben die Position nicht. Wenn Sie also innerhalb einer Assertion
erfassen, wird sie nicht Teil des Abgleichs.

Wenn jedoch die Assertion von einem Unterausdruck gefolgt wurde, der
die in der Assertion referenzierten verwendet, würde es Teil der Gesamtübereinstimmung werden.

Ihr aktueller Regex passt nicht zu Ihrer Zeichenfolge. Um der Zeichenkette zu entsprechen, müssen Sie
entfernen, um die Zeilenumbrüche \n zu entfernen.

(?<= 
     (ADDITIONAL | Additional) # (1) 
) 
[\s\S]+? 
(?= 
     (Languages | LANGUAGES)  # (2) 
) 
0

Versuchen Sie, diese

(?<=ADDITIONAL\s).*?(?=\sLanguages) 

Regex demo

Erläuterung:
(?<=…): Positive Lookbehind sample
\s: "Leerzeichen": Leerzeichen, Tabulator, Newline, Wagenrücklauf, vertikale Registerkarte sample
.: Alle Zeichen außer Zeilenumbruch sample
*: Null oder mehrmals sample
?: Einmal oder keine sample
(?=…): Positive Look-Ahead-sample

Python:

import re 
p = re.compile(ur'(?<=ADDITIONAL\s).*?(?=\sLanguages)', re.IGNORECASE) 
test_str = u"the companys direction ADDITIONAL Awards: 2010 Global Engagement Summit, Languages: Fluent Japanese" 

g = re.findall(p, test_str) 
print g //[u'Awards: 2010 Global Engagement Summit,'] 
+0

Total falsche Antwort. – Aaron

0

Wenn Sie müssen nur Inhalt einschließlicherfassen 0 und LANGUAGES, verwenden Sie einfache Regex wie folgt.

\b(ADDITIONAL .* Languages)\b 

Stellen Sie sicher, dass Sie RE.IGNORECASE-Flag bei der Verwendung in Lösung enthalten.

Siehe Demo auf REGEX101

+0

Sollte (ZUSÄTZLICHE | Zusätzliche) nicht alle kleine Kappe sein. – Aaron

+0

Nicht sicher welcher Ausgang gewünscht wird? https://regex101.com/r/cB7qQ0/1 oder https://regex101.com/r/oK2xT5/1 –

0

Ich denke, Sie verkompliziert etwas einfach, d.h .:

match = re.search("(ADDITIONAL.*?Languages)", subject, re.MULTILINE) 

Regex Erklärung:

(ADDITIONAL.*?Languages) 


Match the regex below and capture its match into backreference number 1 «(ADDITIONAL.*?Languages)» 
    Match the character string “ADDITIONAL” literally (case sensitive) «ADDITIONAL» 
    Match any single character that is NOT a line break character (line feed) «.*?» 
     Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?» 
    Match the character string “Languages” literally (case sensitive) «Languages» 

Regex101 Demo