web-dev-qa-db-fra.com

Comment rechercher un motif dans un fichier texte en utilisant Python) en combinant des opérations regex & string / file et en stockant des occurrences du motif?

Je cherche donc essentiellement un code à 4 chiffres entre deux crochets dans un fichier texte. Je sais que je dois ouvrir le fichier texte, puis analyser ligne par ligne, mais je ne suis pas sûr de la meilleure façon de structurer mon code après avoir vérifié "for line in file".

Je pense que je peux soit le séparer, soit le supprimer, soit la partition, mais j'ai aussi écrit une expression rationnelle sur laquelle j'ai utilisé la compilation. Par conséquent, si cela renvoie un objet match, je ne pense pas pouvoir l'utiliser avec ces opérations basées sur des chaînes. Aussi, je ne suis pas sûr que mon regex soit assez gourmand ou pas ...

J'aimerais stocker toutes les occurrences des hits trouvés sous forme de chaînes dans un tuple ou une liste.

Voici mon regex:

regex = re.compile("(<(\d{4,5})>)?")

Je ne pense pas avoir besoin d'inclure autant de code, vu qu'il est assez basique jusqu'à présent.

38
Carl Carlson
import re
pattern = re.compile("<(\d{4,5})>")

for i, line in enumerate(open('test.txt')):
    for match in re.finditer(pattern, line):
        print 'Found on line %s: %s' % (i+1, match.group())

Quelques notes sur la regex:

  • Vous n'avez pas besoin du ? à la fin et à l'extérieur (...) _ si vous ne voulez pas faire correspondre le nombre avec les crochets, mais voulez seulement le nombre lui-même
  • Il correspond à 4 ou 5 chiffres entre les crochets

Mise à jour: Il est important de comprendre que le correspondance et capture dans une expression rationnelle peut être très différent. La regex de mon extrait ci-dessus correspond au modèle avec, mais je demande à ne capturer que le numéro interne, sans les crochets.

Plus d'informations sur les expressions rationnelles dans python peut être trouvé ici: HOWTO des expressions rationnelles

38
Eli Bendersky

Le faire en une seule lecture:

import re

textfile = open(filename, 'r')
filetext = textfile.read()
textfile.close()
matches = re.findall("(<(\d{4,5})>)?", filetext)

Ligne par ligne:

import re

textfile = open(filename, 'r')
matches = []
reg = re.compile("(<(\d{4,5})>)?")
for line in textfile:
    matches += reg.findall(line)
textfile.close()

Mais encore une fois, les correspondances renvoyées ne seront utiles que pour compter, sauf si vous avez ajouté un compteur de décalage:

import re

textfile = open(filename, 'r')
matches = []
offset = 0
reg = re.compile("(<(\d{4,5})>)?")
for line in textfile:
    matches += [(reg.findall(line),offset)]
    offset += len(line)
textfile.close()

Mais il est toujours plus logique de lire l’ensemble du fichier à la fois.

20
Josiah