web-dev-qa-db-fra.com

Python: trouver l'index du premier chiffre de la chaîne?

Je soupçonne qu’il s’agit d’un problème d’expression régulière - et très basique, donc excuses-moi. 

En Python, si j'ai une chaîne comme 

xdtwkeltjwlkejt7wthwk89lk

comment puis-je obtenir l'index du premier chiffre de la chaîne?

Merci!

33
AP257

Utilisez re.search()

>>> import re
>>> s1 = "thishasadigit4here"
>>> m = re.search("\d", s1)
>>> if m:
...     print "Digit found at position %d" % m.start()
... else:
...     print "No digit in that string"
... 
Digit found at position 13
>>> 
55
bgporter

Voici un moyen meilleur et plus flexible, la regex est excessive ici.

s='xdtwkeltjwlkejt7wthwk89lk'

for i, c in enumerate(s):
    if c.isdigit():
        print i
        break

sortie:

15

Pour obtenir tous les chiffres et leurs positions, une simple expression fera l'affaire

>>> [(i,c) for i,c in enumerate('xdtwkeltjwlkejt7wthwk89lk') if c.isdigit()]
[(15, '7'), (21, '8'), (22, '9')]

En Python 2.7+, vous pouvez créer un dict de digit et sa position.

>>> {c:i for i,c in enumerate('xdtwkeltjwlkejt7wthwk89lk') if c.isdigit()}
{'9': 22, '8': 21, '7': 15}
17
Anurag Uniyal

Cela semble être un bon travail pour un analyseur syntaxique:

>>> from simpleparse.parser import Parser
>>> s = 'xdtwkeltjwlkejt7wthwk89lk'
>>> grammar = """
... integer := [0-9]+
... <alpha> := -integer+
... all     := (integer/alpha)+
... """
>>> parser = Parser(grammar, 'all')
>>> parser.parse(s)
(1, [('integer', 15, 16, None), ('integer', 21, 23, None)], 25)
>>> [ int(s[x[1]:x[2]]) for x in parser.parse(s)[1] ]
[7, 89]
11
Paulo Scardine
import re
mob = re.search('\d', 'xdtwkeltjwlkejt7wthwk89lk')
if mob:
    print mob.start()
8
Christian

Je pensais que je jetterais ma méthode sur la pile. Je ferai à peu près n'importe quoi pour éviter les regex.

sequence = 'xdtwkeltjwlkejt7wthwk89lk'
i = [x.isdigit() for x in sequence].index(True)

Pour expliquer ce qui se passe ici: 

  • [x.isdigit() for x in sequence] va traduire la chaîne en un tableau de booléens indiquant si chaque caractère est un chiffre ou non
  • [...].index(True) renvoie la première valeur d'index dans laquelle True se trouve.
8
alukach

Voici un autre moyen moins regex, plus dans un style fonctionnel. Celui-ci trouve la position de la première occurrence de chaque chiffre qui existe dans la chaîne, puis choisit la plus basse. Une expression rationnelle sera probablement plus efficace, en particulier pour les chaînes plus longues (au moins 10 passages complets dans la chaîne et jusqu'à 20).

haystack = "xdtwkeltjwlkejt7wthwk89lk"
digits   = "012345689"
found    = [haystack.index(Dig) for Dig in digits if Dig in haystack]
firstdig = min(found) if found else None
3
kindall

Comme le disent les autres solutions, nous pouvons utiliser des expressions régulières pour trouver l'index du premier chiffre de la chaîne:

>>> s = 'xdtwkeltjwlkejt7wthwk89lk'
>>> match = re.search(r'\d', s)
>>> print match.start() if match else 'No digits found'
15
>>> s[15] # To show correctness
'7'

Bien que simple, une correspondance d'expression régulière sera excessive pour des chaînes très longues. Un moyen plus efficace consiste à parcourir la chaîne de la manière suivante:

>>> for i, c in enumerate(s):
...     if c.isdigit():
...         print i
...         break
... 
15

Si nous voulions élargir la question à la recherche du premier entier (pas le chiffre) et de ce qu’il était:

>>> s = 'xdtwkeltjwlkejt711wthwk89lk'
>>> for i, c in enumerate(s):
...     if c.isdigit():
...         start = i
...         while i < len(s) and s[i].isdigit():
...             i += 1
...         print 'Integer %d found at position %d' % (int(s[start:i]), start)
...         break
... 
Integer 711 found at position 15
2
marcog

Je suis sûr qu'il existe plusieurs solutions, mais vous pouvez utiliser les expressions régulières:

>>> import re
>>> match = re.search("\d", "xdtwkeltjwlkejt7wthwk89lk")
>>> match.start(0)
15
2

vous pouvez utiliser l'expression régulière 

import re
y = "xdtwkeltjwlkejt7wthwk89lk"

s = re.search("\d",y).start()
1
drhanlau

Pour obtenir tous les index, faites:

idxs = [i for i in range(0, len(string)) if string[i].isdigit()]

Ensuite, pour obtenir le premier index, faites:

idxs[0]
1
Steven Eckhoff
def first_digit_index(iterable):
    try:
        return next(i for i, d in enumerate(iterable) if d.isdigit())
    except StopIteration:
        return -1

Cela n'utilise pas regex et arrête d'itérer dès que le premier chiffre est trouvé.

0
Jacobo de Vera

Un de mes collègues a eu une réponse vraiment géniale à ceci:

import re
result = "  Total files:...................     90"
match = re.match(r".*[^\d](\d+)$", result)
if match:
    print match.group(1)
0
michael toback