Python regex to match IP-address with /CIDR
Asked Answered
M

9

8
m = re.findall("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}",s)

How do I modify it so it will match not only IPv4, but also something with CIDR like 10.10.10.0/24?

Microanalysis answered 19/11, 2010 at 20:48 Comment(0)
B
5
(?:\d{1,3}\.){3}\d{1,3}(?:/\d\d?)?
Bobodioulasso answered 19/11, 2010 at 20:53 Comment(2)
400.123.34.56 is matched but not valid (but asdasdasd's regex has the same problem)Brunei
Just FYI, the '/' may need to be escaped in languages such as Javascript.Marentic
I
3
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?:/\d{1,2}|)

Tested in Expresso

Matched:

64.33.232.212
64.33.232.212/30
Immemorial answered 13/4, 2011 at 21:51 Comment(1)
In my tests using PCRE2 the last forward slash in the expression needs to be escaped: /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?:\/\d{1,2}|)/gmSamaria
I
2

ReGex ( ip_address with/without CIDR )

try this:

str1 = '0.0.0.0/0'
str2 = '255.255.255.255/21'
str3 = '17.2.5.0/21'
str4 = '29.29.206.99'
str5 = '265.265.20.20'

pattern = r"^((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]?)([/][0-3][0-2]?|[/][1-2][0-9]|[/][0-9])?$"


def check_ip(user_input):
    match = re.search(pattern, user_input)
    if match:
        print(f"Yes, IP-address {match.string} is correct")
    else:
        print("No, IP-address is incorrect")


check_ip(str1)
check_ip(str2)
check_ip(str3)
check_ip(str4)
check_ip(str5)

output:

Yes, IP-address 0.0.0.0/0 is correct

Yes, IP-address 255.255.255.255/21 is correct

Yes, IP-address 17.2.5.0/21 is correct

Yes, IP-address 29.29.206.99 is correct

No, IP-address is incorrect
Installation answered 21/8, 2021 at 6:30 Comment(0)
P
1

I had problems using a regex similar to yours. It was matching 1.2.3.4.5 (as 1.2.3.4) and 1111.2.3.4 (as 111.2.3.4). To avoid matching these, I added look ahead/behind assertions:

IP_RE      = re.compile(r"(?<!\d\.)(?<!\d)(?:\d{1,3}\.){3}\d{1,3}(?!\d|(?:\.\d))")
IP_CIDR_RE = re.compile(r"(?<!\d\.)(?<!\d)(?:\d{1,3}\.){3}\d{1,3}/\d{1,2}(?!\d|(?:\.\d))")

The (?<!\d\.)(?<!\d) checks that there isn't a number or octet before your first octet (ie: no 1 before 111.2.3.4). And (?!\d|(?:\.\d)) checks that there isn't a number/octet after your last (ie: no .5 after 1.2.3.4).

Then, to check that the strings these match are valid IPs (eg: not 277.1.1.1), you can use

socket.inet_aton(ip) #raises exception if IP is invalid

Polymerism answered 21/12, 2011 at 14:33 Comment(0)
C
1

There is an all_matching_cidrs(ip, cidrs) function in netaddr's ip module; it takes an ip and matches it with a list of CIDR addresses.

Cement answered 1/6, 2012 at 22:11 Comment(0)
H
1

Just did a really nice regex that also checks the ip format correctness, isn't to long, and matches subnet length optionally:

(25[0-5]|2[0-4]\d|1\d\d|\d\d|\d).(?1).(?1).(?1)\/?(\d\d)?
Halfandhalf answered 25/5, 2019 at 7:0 Comment(1)
Even better: '\b(25[0-5]|2[0-4]\d\b|1\d\d|\d\d|\d)\b\.\b(?1)\b\.\b(?1)\b\.\b(?1)\b\b(\/\d\d|\/\d)?\b'Halfandhalf
C
0

Append "(?:/\d{1,2})?".

That gets you r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?:/\d{1,2})?" for a pattern.

Calibre answered 19/11, 2010 at 20:51 Comment(0)
C
0

this extends your existing expression

\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\\\d{1,2}
Carapace answered 19/11, 2010 at 20:52 Comment(0)
A
0

Best answer I found is:

^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$
Anson answered 7/5, 2022 at 19:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.