Expression régulière pour renvoyer le texte entre parenthèses

113
u'abcde(date=\'2/xc2/xb2\',time=\'/case/test.png\')'

Tout ce dont j'ai besoin est le contenu entre parenthèses.

user469652
la source
Supports? Je ne vois pas de crochets. Vouliez-vous dire la parenthèse?
kzh le
4
Pourquoi ne pas utiliser des guillemets doubles? Cela rendrait la chaîne plus facile à lire, c'estu"abcde(date='2/xc2/xb2',time='/case/test.png')"
kzh
Cette question me rend nerveux rien qu'en la regardant. J'ai l'impression que OP veut vraiment la fonctionnalité astet ne sait tout simplement pas qu'elle existe.
Kevin

Réponses:

247

Si votre problème est vraiment aussi simple, vous n'avez pas besoin de regex:

s[s.find("(")+1:s.find(")")]
Tkerwin
la source
10
et s'il n'y a pas de '(' et ')'? vous obtiendrez s [0: -1]. Ce qui signifie que vous obtiendrez tout ce qui se trouve dans 's': \. Ce sera bien si vous vérifiez que la chaîne a d'abord des parenthèses.
Omar
5
Et si vous aviez "(un peu de texte (un peu de texte entre parenthèses intérieures) un peu de texte)"?
Igor Pomaranskiy
4
Ensuite, le problème n'est pas aussi simple que le problème d'origine et nécessitera une solution différente.
tkerwin
1
Pour la question d'Igor: si vous avez des parenthèses imbriquées comme ça, vous utilisez rfind pour la deuxième partie de l'opération. Voir mon post ci-dessous pour plus de détails à ce sujet.
FaustoW
61

Utilisez re.search(r'\((.*?)\)',s).group(1):

>>> import re
>>> s = u'abcde(date=\'2/xc2/xb2\',time=\'/case/test.png\')'
>>> re.search(r'\((.*?)\)',s).group(1)
u"date='2/xc2/xb2',time='/case/test.png'"
waan
la source
45

Si vous voulez trouver toutes les occurrences:

>>> re.findall('\(.*?\)',s)
[u"(date='2/xc2/xb2',time='/case/test.png')", u'(eee)']

>>> re.findall('\((.*?)\)',s)
[u"date='2/xc2/xb2',time='/case/test.png'", u'eee']
TheSoulkiller
la source
peut être une question stupide, mais pourquoi le "?" nécessaire ? Pourquoi "(. *)" Ne fonctionne-t-il pas?
CutePoison
3
@CutePoison parce qu'il .*est gourmand (prendra le match le plus long) et .*?n'est pas gourmand (prendra le match le plus court)
dopstar
29

En s'appuyant sur la réponse de tkerwin, si vous avez des parenthèses imbriquées comme dans

st = "sum((a+b)/(c+d))"

sa réponse ne fonctionnera pas si vous devez tout prendre entre la première parenthèse ouvrante et la dernière parenthèse fermante pour obtenir (a+b)/(c+d), car rechercher des recherches à partir de la gauche de la chaîne, et s'arrêterait à la première parenthèse fermante.

Pour résoudre ce problème, vous devez utiliser rfindpour la deuxième partie de l'opération, donc cela deviendrait

st[st.find("(")+1:st.rfind(")")]
FaustoW
la source
1
@ALH cette expression n'a pas de parenthèses imbriquées , c'est pourquoi ma réponse est bonne.
FaustoW
6
import re

fancy = u'abcde(date=\'2/xc2/xb2\',time=\'/case/test.png\')'

print re.compile( "\((.*)\)" ).search( fancy ).group( 1 )
Anonyme
la source
2
contents_re = re.match(r'[^\(]*\((?P<contents>[^\(]+)\)', data)
if contents_re:
    print(contents_re.groupdict()['contents'])
Stephen
la source
Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire sur la façon et / ou pourquoi il résout le problème améliorerait la valeur à long terme de la réponse
sshashank124