2
votes

La clause if / else sur l'instruction de boucle avec re.search ne fonctionne pas (python)

Je souhaite analyser les lignes d'un fichier et obtenir les adresses IP.
J'utilise re.search et je souhaite imprimer les deux:
- l'IP
- la chaîne 'None' quand il n'y a pas d'adresse IP

Considérant que le fichier correspond à la variable logfile, j'ai écrit cet extrait:

import re, sys

regexip = r'(?!91.134.143.128)[0-9]{2,3}[.][0-9]{2,3}[.][0-9]{2,3}[.][0-9]{2,3}'
logfile = '91.12.13.14, 65.12.45.78, aaa'

my_iplist = re.findall(regexip,logfile)
for ii in my_iplist:
    if re.search (regexip,logfile):
        print ii
    else:
        print 'None'

Le problème est que je reçois seulement ces résultats ...

91.12.13.14
65.12.45.78

... alors que je veux avoir:

91.12.13.14
65.12.45.78
Aucun

Cette instruction else ne fonctionne pas. Je suppose que je fais quelque chose de mal mais je ne sais pas ce que c'est ..
Toute aide serait très appréciée.
Merci!


5 commentaires

@cdarke: le journal est un fichier journal, je viens de le modifier


C'est parce que re.findall ne renvoie que les correspondances, regardez ce que vous avez dans my_iplist


Votre journal ne contient-il qu'une seule ligne ou est-ce que les , sont en fait des \ n ici? Une ligne peut contenir plusieurs adresses IP, n'est-ce pas?


En remarque, l'utilisation du quantificateur {2,3} est très probablement une erreur, je ne vois pas pourquoi ce ne serait pas {1,3} si vous essayez d'attraper des adresses IPv4 génériques.


Consultez cette réponse pour une approche plus sûre.


3 Réponses :


1
votes

else ne sera jamais exécuté car my_iplist ne contient que des adresses IP valides. re.findall renverra toutes les correspondances. Toutes les chaînes qui ne correspondent pas ne seront pas renvoyées.

Pour obtenir le résultat souhaité, vous devez diviser la chaîne par "," , puis tester chacune par rapport à l'expression régulière:

regexip = r'^(?!91.134.143.128)[0-9]{2,3}[.][0-9]{2,3}[.][0-9]{2,3}[.][0-9]{2,3}$'

Vous devriez également changer votre expression régulière pour avoir des ancres de début et de fin:

lines = logfile.split("\n")
nested_ips = map(lambda x: x.split(", "), lines)
ips = reduce(list.__add__, nested_ips)
for ii in ips:
    if re.search (regexip,ii):
        print ii
    else:
        print 'None'


3 commentaires

Merci pour votre réponse. Cela m'aide beaucoup. Mais quand c'est un fichier journal, je devrais utiliser split ("\ n). Mais le résultat renvoie la ligne entière et pas seulement l'adresse IP.


Vous devez diviser le fichier entier par "\ n" , et diviser chaque ligne par "," . @Julien


Dois-je diviser chaque ligne sur le résultat "ii"?



0
votes

re.findall ne garde pas les choses inégalées, vous devrez donc vérifier ligne par ligne:

91.12.13.14
65.12.45.78
None

Puisque votre fichier journal est un fichier, vous pouvez à la place boucle sur les lignes:

91.12.13.14ezrtqsyu
65.12.45.78 aert
aaa

Voici à quoi ressemble mon fichier logfile.log :

for line in open("logfile.log", "r"):
    match = re.search(regexip, line.strip())
    if match:
        print match.group(0)
     else:
        print "None"

Et la sortie:

for i in logfile.split(','):
    match = re.search(regexip, i)
    if match: 
        print match.group(0)
    else: 
        print "None"


2 commentaires

Merci pour votre réponse. Cela m'aide beaucoup. Mais quand c'est un fichier journal, je devrais utiliser split ("\ n). Mais le résultat renvoie la ligne entière et pas seulement l'adresse IP.


Je pense que vous devriez boucler sur le fichier au lieu d'utiliser split ('\ n')



1
votes

Tout d'abord, utilisez r '(? pour correspondre réellement à adresses IP valides . Vous pouvez filtrer l'adresse IP "indésirable" une fois que vous avez une correspondance.

Maintenant, si vous avez une seule adresse IP par ligne, utilisez re.search comme ceci

if m.group() not in uwelcome_ips:

Si vous avez plusieurs adresses IP indésirables, définissez-les dans une liste:

uwelcome_ips = ["91.134.143.128", "91.134.143.129"]

puis

import sys, re

regexip = r'(?<![0-9])(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}(?![0-9])'
result = []
with open(your_log_file_path, 'r') as f:
    for line in f:
        m = re.search(regexip, line)
        if not m:
            result.append(None)
        else:
            if m.group() != "91.134.143.128":
                result.append(m.group())
            else:
                result.append(None)


1 commentaires

Désolé pour le retard .. super ça marche !! Merci beaucoup pour votre aide !