143 votes

Comment utiliser les expressions rationnelles pour trouver toutes les correspondances qui se chevauchent ?

J'essaie de trouver chaque série de 10 chiffres à l'intérieur d'une plus grande série de chiffres en utilisant re dans Python 2.6.

Il m'est facile de ne pas avoir de chevauchements, mais je veux toutes les correspondances de la série de numéros. Par exemple.

dans "123456789123456789"

Je devrais obtenir la liste suivante :

[1234567891,2345678912,3456789123,4567891234,5678912345,6789123456,7891234567,8912345678,9123456789]

J'ai trouvé des références à un "lookahead", mais les exemples que j'ai vus ne montrent que des paires de nombres plutôt que des groupes plus importants et je n'ai pas été en mesure de les convertir au-delà de deux chiffres.

245voto

bernie Points 44206

Utiliser un groupe de capture à l'intérieur d'un lookahead. Le lookahead capture le texte qui vous intéresse, mais la correspondance réelle est techniquement la sous-chaîne de largeur nulle avant le lookahead, de sorte que les correspondances ne se chevauchent pas techniquement :

import re 
s = "123456789123456789"
matches = re.finditer(r'(?=(\d{10}))', s)
results = [int(match.group(1)) for match in matches]
# results: 
# [1234567891,
#  2345678912,
#  3456789123,
#  4567891234,
#  5678912345,
#  6789123456,
#  7891234567,
#  8912345678,
#  9123456789]

97voto

David C Points 916

Vous pouvez également essayer d'utiliser la fonction tiers regex module (pas re ), qui prend en charge les correspondances qui se chevauchent.

>>> import regex as re
>>> s = "123456789123456789"
>>> matches = re.findall(r'\d{10}', s, overlapped=True)
>>> for match in matches: print(match)  # print match
...
1234567891
2345678912
3456789123
4567891234
5678912345
6789123456
7891234567
8912345678
9123456789

16voto

eyquem Points 9942

J'aime bien les regex, mais elles ne sont pas nécessaires ici.

Simplement

s =  "123456789123456789"

n = 10
li = [ s[i:i+n] for i in xrange(len(s)-n+1) ]
print '\n'.join(li)

résultat

1234567891
2345678912
3456789123
4567891234
5678912345
6789123456
7891234567
8912345678
9123456789

3voto

Michael Points 312

En complément de la réponse acceptée, la solution suivante fonctionne également à l'heure actuelle

import re
s = "123456789123456789"
matches = re.findall(r'(?=(\d{10}))',s)
results = [int(match) for match in matches]

0voto

Avi Cohen Points 1140

De manière conventionnelle :

import re

S = '123456789123456789'
result = []
while len(S):
    m = re.search(r'\d{10}', S)
    if m:
        result.append(int(m.group()))
        S = S[m.start() + 1:]
    else:
        break
print(result)

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