2016-03-27 10 views
0

Eine Aussage wie:Wie Regex eine Aussage mit optionalen Endteil übereinstimmen?

[string1...] string2 in english/chinese (string3...) 

string3 ist in () und ist optional.

Ich schreibe einen RegexMuster in Python:

(\[(?P<string1>.*)\])\s*(?P<string2>.*)\s(\((?P<string3>.*)\))? 

Aber wie * ist gierig Spiel und string3 wird innerhalb Zeichenfolge2 analysiert werden.

Ich benutze Look-Ahead-Spiel string3 wie:

(\[(?P<string1>.*)\])\s*(?P<string2>.*(?=\())\s*((?P<string3>.*)\))? 

Aber ist auch kein Spiel.

Wie soll ich die drei Übereinstimmung Teil bekommen, und der letzte Teil ist optional innerhalb ()?

+0

@anubhava keine anderen möglichen Eingaben, die alle in diesem Muster sind. –

+0

Hat die Eingabe am Ende ein Literal '?', Wie in Frage gezeigt? – anubhava

+1

@anubhava Entschuldigung, das letzte '?' Zeigen String3 ist optional, ich werde es im Klartext entfernen –

Antwort

2

Sie diese Regex basierend auf Negation Muster $ mit Anker verwenden:

\[(?P<string1>[^\]]*)\]\s*(?P<string2>[^()]*)(?:\s+\((?P<string3>.*)\))?$ 

Hier verwenden wir 2 Negation Untermuster:

[^\]]* # matches 0 or more of any char that 
[^()]* # matches 0 or more of any char that is not (and) 

RegEx Demo

+1

Warum der Downvote hier? – Jan

+0

Ich habe keine Ahnung, Jan, warum Downvote innerhalb von Sekunden der Veröffentlichung erschien. Sieht wie ein Auslöser aus, glücklicher Downvoter kümmerte sich nicht einmal darum, die Antwort zu lesen. – anubhava

+1

Etwas Entschädigung von mir dann (happy upvoter, das ist ;-) – Jan

2

Soetwas ?

^(?P<string1>\[[^]]+\])  # anchor it to the start 
(?P<string2>[^(\n]+)   # everything not a (
(?:\((?P<string3>[^)]+)\))?$ # sth. in(), optional 

Mit multiline und verbose Modus finden a demo on regex101.com.
In Python:

import re 
string = "[string1...] string2 in english/chinese (string3...)" 
rx = re.compile(""" 
    ^(?P<string1>\[[^]]+\])  # anchor it to the start 
    (?P<string2>[^(\n]+)   # everything not a (
    (?:\((?P<string3>[^)]+)\))?$ # sth. in(), optional 
""", re.MULTILINE|re.VERBOSE) 
matches = rx.findall(string) 
+0

Hallo, in String2, warum '\ n' für Newline ausschließen? –

+0

@TankyWoo: wegen der Demo (regex101), brauchen Sie es nicht in Ihrem realen Beispiel. – Jan

2

In Ihrem regex sehe ich \( kurz vor string 3, was bedeutet, dass die String-3 in Klammern eingeschlossen ist. In diesem Fall können Sie string 2 bis zu keiner linken Klammer vergleichen, die so gefunden wird.

Regex:(\[(?P<string1>.*?)\])\s*(?P<string2>[^\(]*)\s*(\((?P<string3>.*)\))?

Notiere die [^\(] in Gruppe string2

Regex101 Demo

Verwandte Themen