116 votes

retourne la chaîne avec la première correspondance Regex

Je veux obtenir la première correspondance d'une expression rationnelle.

Dans ce cas, j'ai obtenu une liste :

text = 'aa33bbb44'
re.findall('\d+',text)

['33', '44']

Je pourrais extraire le premier élément de la liste :

text = 'aa33bbb44'
re.findall('\d+',text)[0]

'33'

Mais cela ne fonctionne que s'il y a au moins une correspondance, sinon j'obtiendrai une erreur :

text = 'aazzzbbb'
re.findall('\d+',text)[0]

IndexError : l'index de la liste est hors de portée

Dans ce cas, je pourrais définir une fonction :

def return_first_match(text):
    try:
        result = re.findall('\d+',text)[0]
    except Exception, IndexError:
        result = ''
    return result

Existe-t-il un moyen d'obtenir ce résultat sans définir une nouvelle fonction ?

0 votes

Pour moi, la réponse acceptée n'a pas fonctionné. J'ai dû supprimer l'accès à l'index du tableau et utiliser len(re.findAll)==0 à la place.

136voto

Stefan Pochmann Points 5022

Vous pourriez intégrer le '' par défaut dans votre regex en ajoutant |$ :

>>> re.findall('\d+|$', 'aa33bbb44')[0]
'33'
>>> re.findall('\d+|$', 'aazzzbbb')[0]
''
>>> re.findall('\d+|$', '')[0]
''

Fonctionne également avec re.search soulignés par d'autres :

>>> re.search('\d+|$', 'aa33bbb44').group()
'33'
>>> re.search('\d+|$', 'aazzzbbb').group()
''
>>> re.search('\d+|$', '').group()
''

1 votes

Super, est-ce que search/.group a un avantage sur findall/[0] ?

7 votes

@LuisRamonRamirezRodriguez Il peut s'arrêter dès qu'il a trouvé une correspondance, il n'a pas à traiter le reste du texte et n'a pas à stocker toutes les correspondances. C'est donc plus efficace. En outre, il peut littéralement "est ce que tu veux" comme l'a dit @TimPeters. Cela pourrait être un avantage lorsque vous ou quelqu'un d'autre, à un moment donné, le lira et se demandera "Pourquoi findall utilisé ?" .

63voto

Iron Fist Points 5505

Si vous n'avez besoin que de la première correspondance, alors utilisez re.search au lieu de re.findall :

>>> m = re.search('\d+', 'aa33bbb44')
>>> m.group()
'33'
>>> m = re.search('\d+', 'aazzzbbb')
>>> m.group()
Traceback (most recent call last):
  File "<pyshell#281>", line 1, in <module>
    m.group()
AttributeError: 'NoneType' object has no attribute 'group'

Vous pouvez alors utiliser m comme condition de contrôle :

>>> m = re.search('\d+', 'aa33bbb44')
>>> if m:
        print('First number found = {}'.format(m.group()))
    else:
        print('Not Found')

First number found = 33

18voto

Bill Points 123

J'irais avec :

r = re.search("\d+", ch)
result = return r.group(0) if r else ""

re.search ne cherche que le premièrement dans la chaîne de toute façon, donc je pense que cela rend votre intention légèrement plus claire que l'utilisation de findall .

10voto

Tim Peters Points 16225

Vous ne devriez pas utiliser .findall() du tout - .search() est ce que vous voulez. Il trouve la correspondance la plus à gauche, ce qui est ce que vous voulez (ou retourne None si aucune correspondance n'existe).

m = re.search(pattern, text)
result = m.group(0) if m else ""

C'est à vous de décider si vous voulez mettre cela dans une fonction. C'est inhabituel de vouloir retourner une chaîne vide si aucune correspondance n'est trouvée, c'est pourquoi rien de tel n'est intégré. Il est impossible de se tromper sur le fait que .search() à elle seule, trouve une correspondance (elle renvoie None si ce n'est pas le cas, ou un SRE_Match si c'était le cas).

3voto

ketan vijayvargiya Points 3655

Vous pouvez le faire :

x = re.findall('\d+', text)
result = x[0] if len(x) > 0 else ''

Notez que votre question n'est pas exactement liée aux regex. Il s'agit plutôt de savoir comment trouver en toute sécurité un élément dans un tableau, s'il n'en a pas.

2 votes

Je remplacerais 'len(x) > 0' par simplement 'x' ici.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X