2009-04-19 1 views
79

Wie mache ich eine Python Regex wie "(. *)", So dass, gegeben "a (b) c (d) e" Python "b" statt "b) c (d "Python nicht-gierige Regexe

Ich weiß, dass ich" [^)] "anstelle von". "Verwenden kann, aber ich suche nach einer allgemeineren Lösung, die meine Regex ein wenig sauberer hält. Gibt es eine Möglichkeit, Python zu sagen "Hey, passe das so schnell wie möglich an"?

Antwort

11

Wäre das nicht \\(.*?\\) Arbeit? Das ist die nicht-gierige Syntax.

51
>>> x = "a (b) c (d) e" 
>>> re.search(r"\(.*\)", x).group() 
'(b) c (d)' 
>>> re.search(r"\(.*?\)", x).group() 
'(b)' 

According to the docs:

Die '*', '+' und '?' Qualifier sind alle gierig; Sie stimmen so viel Text wie möglich ab. Manchmal ist dieses Verhalten nicht erwünscht; Wenn der RE <.*> mit '<H1>title</H1>' verglichen wird, wird die gesamte Zeichenfolge und nicht nur '<H1>' übereinstimmen. Hinzufügen von '?' nach dem Qualifikationsmerkmal bewirkt, dass die Übereinstimmung in nicht-gieriger oder minimaler Weise durchgeführt wird; so wenige Zeichen wie möglich werden übereinstimmen. Die Verwendung von .*? im vorherigen Ausdruck entspricht nur '<H1>'.

+1

[HTML nie mit Regex analysieren] (https://Stackoverflow.com/a/1732454) –

2

Möchten Sie, dass "(b)" übereinstimmt? Tun Sie, wie Zitrax und Paolo vorgeschlagen haben. Soll es mit "b" übereinstimmen? Haben

>>> x = "a (b) c (d) e" 
>>> re.search(r"\((.*?)\)", x).group(1) 
'b' 
2

Mit einem ungreedy Spiel ist ein guter Anfang, aber ich würde auch vorschlagen, dass Sie jegliche Verwendung von .* denken - was ist das?

groups = re.search(r"\([^)]*\)", x) 
5

Wie die anderen gesagt haben mit der? Der Modifizierer auf dem * Quantifier löst Ihr unmittelbares Problem, aber seien Sie vorsichtig, Sie beginnen sich in Bereiche zu verirren, in denen Regexe nicht mehr funktionieren und Sie stattdessen einen Parser benötigen. Zum Beispiel wird der String "(foo (bar)) baz" Ihnen Probleme bereiten.