web-dev-qa-db-fra.com

Python regex non gourmands

Comment créer un regex python comme "(. *)" Tel que, étant donné "a (b) c (d) e" python correspond ") b "au lieu de" b) c (d "?

Je sais que je peux utiliser "[^)]" au lieu de ".", Mais je cherche une solution plus générale qui garde ma regex un peu plus propre. Est-il possible de dire python "hé, faites-le correspondre le plus tôt possible"?

120
So8res

Vous recherchez le tout-puissant '*?'

http://docs.python.org/3/howto/regex.html#greedy-versus-non-greedy

les qualificatifs non-gourmands * ?, + ?, ??, ou {m, n}? [...] correspond le moins de texte possible .

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

Selon la documentation :

Les qualificatifs '*', '+' Et '?' Sont tous gloutons; ils correspondent autant de texte que possible. Parfois, ce comportement n’est pas souhaité; si le RE <.*> est comparé à "<H1>title</H1>", il correspondra à la chaîne entière et pas seulement "<H1>". En ajoutant '?' Après le qualificatif, le match est exécuté de manière peu gourmande ou minimale; autant de caractères que possible seront appariés. L'utilisation de .*? Dans l'expression précédente correspond uniquement à '<H1>'.

60
Paolo Bergantino

La fonction \\(.*?\\) ne fonctionnerait-elle pas? C'est la syntaxe non gourmande.

13
Zitrax

Comme les autres l'ont dit en utilisant le? Un modificateur sur le * quantificateur résoudra votre problème immédiat, mais attention, vous commencez à vous perdre dans des domaines où les expressions rationnelles cessent de fonctionner et vous avez besoin d'un analyseur. Par exemple, la chaîne "(foo (bar)) baz" vous causera des problèmes.

5
Chas. Owens

Utiliser un match sans égoïsme est un bon début, mais je vous suggère également de reconsidérer toute utilisation de .* -- Et ça?

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

Voulez-vous qu'il corresponde à "(b)"? Faites comme Zitrax et Paolo l'ont suggéré. Voulez-vous qu'il corresponde à "b"? Faire

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