web-dev-qa-db-fra.com

Expression régulière pour renvoyer tous les caractères entre deux caractères spéciaux

Comment pourrais-je utiliser regx pour retourner tous les caractères entre deux crochets. Voici un exemple:

foobar['infoNeededHere']ddd
needs to return infoNeededHere

J'ai trouvé une expression régulière pour le faire entre crochets, mais toutes les tentatives pour le faire fonctionner avec des crochets ont échoué. Voici cette expression régulière: (?<={)[^}]*(?=}) et voici ma tentative de le pirater

(?<=[)[^}]*(?=])

Solution finale:

import re

str = "foobar['InfoNeeded'],"
match = re.match(r"^.*\['(.*)'\].*$",str)
print match.group(1)
20
user1130161

^.*\['(.*)'\].*$ correspondra à une ligne et capturera ce que vous voulez dans un groupe.

Vous devez échapper au [ et ] avec \

La documentation sur le lien rubular.com proof expliquera comment l'expression est formée.

20
user177800

Si vous débutez avec [~ # ~] reg [~ # ~] (gular) [~ # ~] ex [~ # ~] (pressions) vous en apprenez plus sur Python Docs . Ou, si vous voulez une introduction plus douce, vous pouvez consulter le HOWTO . Ils utilisent la syntaxe de style Perl.

Regex

L'expression dont vous avez besoin est .*?\[(.*)\].*. Le groupe que vous souhaitez sera _\1_.
- _.*?_ : _._ correspond à n'importe quel caractère sauf une nouvelle ligne. _*_ est un méta-caractère et signifie Répétez cette opération 0 fois ou plus. _?_ rend le _*_ non gourmand, c'est-à-dire que _._ fera correspondre le moins de caractères possible avant de frapper un '['.
- _\[_ : _\_ échappe les méta-caractères spéciaux, qui dans ce cas, est _[_. Si nous ne faisions pas cela, _[_ ferait quelque chose de très étrange à la place.
- _(.*)_ : Parenthèses 'groupes' ce qu'il y a dedans et vous pourrez plus tard récupérer les groupes par leurs identifiants ou noms numériques (s'ils sont donné un).
- _\].*_ : Vous devriez en savoir suffisamment maintenant pour savoir ce que cela signifie.

La mise en oeuvre

Tout d'abord, importez le module re - ce n'est pas un module intégré - à l'endroit où vous souhaitez utiliser l'expression.

Ensuite, utilisez re.search(regex_pattern, string_to_be_tested) pour rechercher le modèle dans la chaîne à tester. Cela renverra un MatchObject que vous pouvez stocker dans une variable temporaire. Vous devez ensuite appeler sa méthode group() et passer 1 en argument (pour voir le "groupe 1" que nous avons capturé en utilisant les parenthèses plus tôt). Je devrais maintenant ressembler à:

_>>> import re
>>> pat = r'.*?\[(.*)].*'             #See Note at the bottom of the answer
>>> s = "foobar['infoNeededHere']ddd"
>>> match = re.search(pat, s)
>>> match.group(1)
"'infoNeededHere'"
_

Une alternative

Vous pouvez également utiliser findall() pour trouver toutes les correspondances qui ne se chevauchent pas en modifiant l'expression régulière en _(?>=\[).+?(?=\])_.
- _(?<=\[)_ : _(?<=)_ est appelé une assertion de recherche et recherche une expression précédente la correspondance réelle.
- _.+?_ : _+_ est exactement comme _*_ sauf qu'il correspond à one ou plus de répétitions. Il est rendu non gourmand par _?_.
- _(?=\])_ : _(?=)_ est un regard -à venir assertion et recherche une expression suivant ​​le match sans le capturer.
Votre code devrait maintenant ressembler à:

_>>> import re
>>> pat = r'(?<=\[).+?(?=\])'  #See Note at the bottom of the answer
>>> s = "foobar['infoNeededHere']ddd[andHere] [andOverHereToo[]"
>>> re.findall(pat, s)
["'infoNeededHere'", 'andHere', 'andOverHereToo['] 
_

Remarque: Utilisez toujours des chaînes brutes Python en ajoutant un 'r' avant la chaîne (par exemple: _r'blah blah blah'_).

10x pour la lecture! J'ai écrit cette réponse alors qu'il n'y en avait pas encore acceptée, mais au moment où je l'ai terminée, 2 minerais sont arrivés et un a été accepté. :( x <

31
Yatharth Agarwal

S'il n'y a qu'un seul de ces jetons [.....] Par ligne, alors vous n'avez pas du tout besoin d'utiliser des expressions régulières:

In [7]: mystring = "Bacon, [eggs], and spam"

In [8]: mystring[ mystring.find("[")+1 : mystring.find("]") ]
Out[8]: 'eggs'

S'il y en a plusieurs par ligne, vous devrez modifier l'expression régulière de Jarrod ^.*\['(.*)'\].*$ pour qu'elle corresponde plusieurs fois par ligne et pour ne pas être gourmand. (Utilisez le quantificateur .*? Au lieu du quantificateur .*.)

In [15]: mystring = "[Bacon], [eggs], and [spam]."

In [16]: re.findall(r"\[(.*?)\]",mystring)
Out[16]: ['Bacon', 'eggs', 'spam']
10
Li-aung Yip