2012-06-29 13 views
12

Próbuję wykonać test w celu sprawdzenia, czy wejście sys.argv mecze regex adresu IP ...Korzystanie regex pasujące do adresów IP w Pythonie

Jako prosty test, mam następujących ...

import re 

pat = re.compile("\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}") 
test = pat.match(hostIP) 
if test: 
    print "Acceptable ip address" 
else: 
    print "Unacceptable ip address" 

jednak kiedy mijam losowych wartości do niej wraca „Dopuszczalny adres IP” w większości przypadków, z wyjątkiem, gdy mam „adres”, który jest w zasadzie równoważne \d+.

+0

Czy chcesz zaakceptować 999.999.999.999 jako "prawidłowy" adres IP? :) –

+0

Tylko IPv4; bez IPv6? – belacqua

+0

Zobacz http://stackoverflow.com/questions/319279/how-to-validate-ip-address-in-python?lq=1 i http://stackoverflow.com/questions/10191442/check-hostnames-and- ip-addresses-v4-and-v6-using-a-single-python-regex? rq = 1 – belacqua

Odpowiedz

18

Trzeba zmodyfikować regex w następujący sposób

pat = re.compile("^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$") 

to dlatego . jest wieloznaczny, który oznacza „każdy znak”

+0

Aby upewnić się, że ciąg znaków jest dokładnie taki, jak podano, możesz dodać '^' do początku i '$' do końca . W przeciwnym razie możliwe jest dopasowanie ciągu takiego jak '10.0.0.1: 1234', w którym go nie chcesz. – javex

+0

@javex masz rację – DonCallisto

+0

OMG ... FFS !!! taki "błąd szkolnego chłopca" ... Naprawdę pomagałem komuś w innym dniu z regex i "." ... GHHHH! ... zostałem ustawiony na problem z pytonem! Bardzo dziękuję – MHibbin

2

Próbujesz użyć. jak . nie jako symbol wieloznaczny dla żadnej postaci. Zamiast tego należy wpisać \., aby wskazać kropkę.

27

Korzystanie regex do sprawdzania poprawności adresu IP to zły pomysł - tak przejdzie 999.999.999.999 jako ważny. Spróbuj tego podejścia, używając zamiast tego gniazda - o wiele lepszą walidację i tak samo łatwe, jeśli nie łatwiejsze do wykonania.

import socket 

def valid_ip(address): 
    try: 
     socket.inet_aton(address) 
     return True 
    except: 
     return False 

print valid_ip('10.10.20.30') 
print valid_ip('999.10.20.30') 
print valid_ip('gibberish') 

Jeśli naprawdę chcesz używać podejście parse-the-hosta zamiast kod ten zrobi to dokładnie:

def valid_ip(address): 
    try: 
     host_bytes = address.split('.') 
     valid = [int(b) for b in host_bytes] 
     valid = [b for b in valid if b >= 0 and b<=255] 
     return len(host_bytes) == 4 and len(valid) == 4 
    except: 
     return False 
+5

Regex może działać, ale twoje podejście jest lepsze. – belacqua

+0

Tak ... mógłbyś napisać przerażające wyrażenie regularne, które pasuje do "255", ale prawdopodobnie lepiej tego uniknąć :) –

+1

+1 ode mnie też za to podejście (awans godzinę temu :) – Levon

9

regex dla IP v4:

^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ 

inaczej wziąć niepoprawny adres IP, taki jak 999.999.999.999, 256.0.0.0 itp.

+0

wow!Myślę, że pozostanę przy metodzie gniazdek, ale dzięki. Zanotuję to ... Zastanawiałem się, jak to będzie wyglądać. :-) – MHibbin

+0

Fajnie. Jeśli nie używasz w Pythonie, ale PRCE, może być nieco krótszy z podprogramów: '^ ((25 [0-5] | 2 [0-4] [0-9] | [01]? [0-9] { 1,2}) \.) {3} (? 2) $ ' https://regex101.com/r/sE3hK5/1 –

-1

Adres IP wykorzystuje następujące uwierzytelnienie:

  1. 255 ---> 250-255
  2. 249 ---> 200-249
  3. 199 ---> 100-199
  4. 99 ---> 10-99
  5. 9 ---> 1-9

    import re  
    k = 0 
    while k < 5 : 
        i = input("\nEnter Ip address : ") 
        ip = re.match("^([1][0-9][0-9].|^[2][5][0-5].|^[2][0-4][0-9].|^[1][0-9][0-9].|^[0-9][0-9].|^[0-9].)([1][0-9][0-9].|[2][5][0-5].|[2][0-4][0-9].|[1][0-9][0-9].|[0-9][0-9].|[0-9].)([1][0-9][0-9].|[2][5][0-5].|[2][0-4][0-9].|[1][0-9][0-9].|[0-9][0-9].|[0-9].)([1][0-9][0-9]|[2][5][0-5]|[2][0-4][0-9]|[1][0-9][0-9]|[0-9][0-9]|[0-9])$",i) 
        k = k + 1 
        if ip: 
         print ("\n=====================") 
         print ("Valid IP address") 
         print ("=====================") 
         break 
        else : 
         print ("\nInvalid IP") 
    else : 
        print ("\nAllowed Max 5 times") 
    

Odpowiedz mi, jeśli masz wątpliwości?

-4
yourip = '10.10.10.10' 

if [0<=int(x)<256 for x in re.split('\.',re.match(r'^\d+\.\d+\.\d+\.\d+$',yourip).group(0))].count(True)==4: 

    print "valid ip" 

else: 

    print "invalid ip" 
+1

Tak więc oprócz faktu, że' twoje-ip' nie jest tak naprawdę zmienną nazwa, muszę powiedzieć, że jest to dość dziwne i niejasne użycie słów "skuteczny" i "prosty", o których wcześniej nie wiedziałem. – Carpetsmoker

+0

Właśnie wspomniałem o zmiennej "twoje-ip", co do czytelności, a nie o tym, aby ją rozważyć lub skopiować. Wspomniałem słowa "proste" i "skuteczne", ponieważ nie trzeba pisać długiego wyrażenia regularnego, aby potwierdzić IP. Użyłem spisu ze zrozumieniem i re.split, co sprawiło, że było to proste. możesz zrozumieć, widząc warunek jeśli. – Ranga

1
def ipcheck(): 
# 1.Validate the ip adderess 
input_ip = input('Enter the ip:') 
flag = 0 

pattern = "^\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}$" 
match = re.match(pattern, input_ip) 
if (match): 
    field = input_ip.split(".") 
    for i in range(0, len(field)): 
     if (int(field[i]) < 256): 
      flag += 1 
     else: 
      flag = 0 
if (flag == 4): 
    print("valid ip") 
else: 
    print('No match for ip or not a valid ip') 
0

Oto wariant zgodny z IPv4/6 za to samo:

pattern = re.compile("^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(\.\d{1,3}\.\d{1,3})?$") 

To będzie pasujących adresów IPv4 i IPv6. Zmiana to (\.\d{1,3}\.\d{1,3})? i będzie pasować do tych dodatkowych .xx.xx, jeśli są obecne.

-1
import re 

st1 = 'This is my IP Address10.123.56.25 789.356.441.561 127 255 123.55 192.168.1.2.3 192.168.2.2 str1' 

Oto mój adres IP jest ważny tylko 192.168.2.2 i zakładając 10.123.56.25 nie jest ważny, gdyż jeden jest połączony z jakimś ciągiem i 192.168.1.2.3 nieprawidłowy.

pat = r'\s(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\s|$))' 

match = re.search(pat,st1) 

print match.group() 

================ RESTART: C:/Python27/Srujan/re_practice.py ================ 
192.168.2.2 

Będzie to grep dokładny adres IP, możemy ignorować wygląd wzoru jak adres IP, ale nie jest ważne jeden. Np .: 'Address10.123.56.25', '789.356.441.561' '192.168.1.2.3'.

Proszę opisać, czy są wymagane jakiekolwiek modyfikacje.

-1

Działa to dla Pythona 2.7:

import re 
a=raw_input("Enter a valid IP_Address:") 
b=("[0-9]+"+".")+"{3}" 
if re.match(b,a) and b<255: 
    print "Valid" 
else: 
    print "invalid" 
3

natknąłem się w takiej samej sytuacji, znalazłem odpowiedź z wykorzystaniem biblioteki gniazdo pomocne, ale nie zapewnia wsparcia dla adresów IPv6. Znaleźli lepszy sposób na to:

Niestety to działa tylko dla python3

import ipaddress 

def valid_ip(address): 
    try: 
     print ipaddress.ip_address(address) 
     return True 
    except: 
     return False 

print valid_ip('10.10.20.30') 
print valid_ip('2001:DB8::1') 
print valid_ip('gibberish') 
+0

Powoduje to zwrócenie 0.0.0.0 również –

+1

@rakeshpatanga, tak, jest to prawidłowy adres IP. – Deepak

0
import re 
ipv=raw_input("Enter an ip address") 
a=ipv.split('.') 
s=str(bin(int(a[0]))+bin(int(a[1]))+bin(int(a[2]))+bin(int(a[3]))) 
s=s.replace("0b",".") 
m=re.search('\.[0,1]{1,8}\.[0,1]{1,8}\.[0,1]{1,8}\.[0,1]{1,8}$',s) 
if m is not None: 
    print "Valid sequence of input" 
else : 
    print "Invalid input sequence" 

Wystarczy keep it simple Użyłem tego podejścia. Proste w celu wyjaśnienia, jak naprawdę oceniany jest adres IPv4. Sprawdzanie, czy jego liczba binarna nie jest wymagana. Mam nadzieję, że Ci się spodoba.

Powiązane problemy