web-dev-qa-db-fra.com

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

Je veux obtenir le premier match d'une regex.

Dans ce cas, j'ai eu 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 je vais avoir une erreur:

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

IndexError: index de liste hors limites

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?

Vous pouvez incorporer le '' default 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 signalé par d’autres:

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

Si vous n'avez besoin que de la première correspondance, 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'
_

Ensuite, vous pouvez utiliser m comme condition de vérification, par exemple:

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


First number found = 33
_
31
Iron Fist

J'irais avec:

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

re.search ne cherche de toute façon que le premier dans la chaîne. Je pense donc que votre intention est un peu plus claire que d'utiliser findall.

6
Bill

Vous ne devriez pas utiliser .findall() du tout - .search() est ce que vous voulez. Il trouve la correspondance la plus à gauche, ce que vous voulez (ou renvoie None s'il n'y a pas de correspondance).

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

Que vous souhaitiez mettre cela dans une fonction dépend de vous. Il est inhabituel de vouloir retourner une chaîne vide si aucune correspondance n'est trouvée, ce qui explique pourquoi rien de tel n'est intégré. Il est impossible de ne pas savoir si .search() trouve seul une correspondance. (elle retourne None si ce n'est pas le cas, ou un objet SRE_Match s'il le faisait).

5
Tim Peters

Tu peux faire:

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

Notez que votre question n'est pas exactement liée à regex. Comment pouvez-vous trouver en toute sécurité un élément d'un tableau, s'il n'en a pas.

2
ketan vijayvargiya

Cela fonctionnerait peut-être un peu mieux au cas où une plus grande quantité de données en entrée ne contiendrait pas la pièce que vous souhaitiez car excepté à un coût plus élevé.

def return_first_match(text):
    result = re.findall('\d+',text)
    result = result[0] if result else ""
    return result
1
Marko Mackic