60 votes

vérifier si une chaîne de caractères correspond à un motif d'adresse IP en python ?

Quel est le moyen le plus rapide de vérifier si une chaîne de caractères correspond à un certain motif ? Les expressions rationnelles sont-elles le meilleur moyen ?

Par exemple, j'ai un tas de chaînes de caractères et je veux vérifier pour chacune d'entre elles s'il s'agit d'une adresse IP valide (valide dans ce cas signifie un format correct), est-ce que la façon la plus rapide de le faire est d'utiliser des expressions rationnelles ? Je ne sais pas si c'est le cas, mais je ne sais pas non plus s'il y a quelque chose de plus rapide avec un formatage de chaîne ou quelque chose comme ça.

C'est ce que j'ai fait jusqu'à présent :

for st in strs:
    if re.match('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', st) != None:
       print 'IP!'

104voto

Mark Byers Points 318575

mise à jour : La réponse originale ci-dessous est bonne pour 2011, mais depuis 2012, il est probablement préférable d'utiliser la fonction Python adresse IP module stdlib - Outre la vérification de la validité de l'IP pour IPv4 et IPv6, il peut faire beaucoup d'autres choses. </update>

On dirait que vous essayez de valider les adresses IP . Une expression régulière n'est probablement pas le meilleur outil pour cela.

Si vous souhaitez accepter toutes les adresses IP valides (y compris certaines adresses dont vous ne saviez probablement même pas qu'elles étaient valides), vous pouvez utiliser l'option IPy (Source) :

from IPy import IP
IP('127.0.0.1')

Si l'adresse IP n'est pas valide, une exception sera levée.

Vous pouvez également utiliser socket (Source) :

import socket
try:
    socket.inet_aton(addr)
    # legal
except socket.error:
    # Not legal

Si vous voulez vraiment ne faire correspondre que les IPv4 avec 4 parties décimales, vous pouvez séparer les points et tester que chaque partie est un entier entre 0 et 255.

def validate_ip(s):
    a = s.split('.')
    if len(a) != 4:
        return False
    for x in a:
        if not x.isdigit():
            return False
        i = int(x)
        if i < 0 or i > 255:
            return False
    return True

Notez que votre expression régulière n'effectue pas cette vérification supplémentaire. Elle accepterait 999.999.999.999 comme adresse valide.

58voto

zakiakhmad Points 305

Si vous utilisez Python3 vous pouvez utiliser ipaddress module http://docs.python.org/py3k/library/ipaddress.html . Exemple :

>>> import ipaddress

>>> ipv6 = "2001:0db8:0a0b:12f0:0000:0000:0000:0001"
>>> ipv4 = "192.168.2.10"
>>> ipv4invalid = "266.255.9.10"
>>> str = "Tay Tay"

>>> ipaddress.ip_address(ipv6)
IPv6Address('2001:db8:a0b:12f0::1')

>>> ipaddress.ip_address(ipv4)
IPv4Address('192.168.2.10')

>>> ipaddress.ip_address(ipv4invalid)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/lib/python3.4/ipaddress.py", line 54, in ip_address
    address)
ValueError: '266.255.9.10' does not appear to be an IPv4 or IPv6 address

>>> ipaddress.ip_address(str)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/lib/python3.4/ipaddress.py", line 54, in ip_address
    address)
ValueError: 'Tay Tay' does not appear to be an IPv4 or IPv6 address

16voto

Alvaro Points 103

Avec Python 3.6, je pense que c'est beaucoup plus simple car le module ipaddress est déjà inclus :

import ipaddress

    def is_ipv4(string):
        try:
            ipaddress.IPv4Network(string)
            return True
        except ValueError:
            return False

14voto

Alex Martelli Points 330805

Je suis normalement l'un des rares experts Python à défendre fermement les expressions régulières (elles ont une assez mauvaise réputation dans la communauté Python), mais ce n'est pas l'un de ces cas -- accepter (disons) des expressions régulières est une erreur. '333.444.555.666' comme une "adresse IP" est vraiment et si vous devez procéder à d'autres vérifications après avoir fait correspondre l'ER, une grande partie de l'intérêt de l'utilisation d'un ER est de toute façon perdue. Je souscris donc pleinement aux recommandations de @Mark : IPy pour la généralité et l'élégance (y compris la prise en charge d'IPv6 si vous le souhaitez !), les opérations sur les chaînes de caractères et les vérifications d'int si vous n'avez besoin que d'IPv4 (mais réfléchissez à deux fois à cette limitation, et réfléchissez encore une fois -- l'heure d'IPv6 a sonné ). manière venir!-) :

def isgoodipv4(s):
    pieces = s.split('.')
    if len(pieces) != 4: return False
    try: return all(0<=int(p)<256 for p in pieces)
    except ValueError: return False

Je préfère de loin cela à un RE alambiqué visant à faire correspondre uniquement les nombres compris entre 0 et 255!-)

6voto

Tony Veijalainen Points 2579

Une validation de plus sans re :

def validip(ip):
    return ip.count('.') == 3 and  all(0<=int(num)<256 for num in ip.rstrip().split('.'))

for i in ('123.233.42.12','3234.23.453.353','-2.23.24.234','1.2.3.4'):
    print i,validip(i)

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