简体   繁体   中英

Regex for ipv4 address without 0.x.x.x if x != 0

I'm doing a regex for ipv4 address, It's very interesting that Ubuntu and some RFC references state that 0.xxx if x != 0 are reserved, so invalid. What should be the more optimal regex for this? I have this one:

import re
matcher = re.compile(r'^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]|[1-9])(\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])){3}\Z^(0)(.0){3}\Z')

For example:

0.1.2.3 => should be invalid
1.0.0.0 => should be valid
0.0.0.0 => should be valid

I think the regex you looking for is:

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

You can test it here

Here is the regex that meets the requirements:

^(?!0+(?:\.0*[1-9][0-9]*){3}$)(?: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}$

See its online demo .

The main points are:

  • (?!0+(?:\\.0*[1-9][0-9]*){3}$) - a (?!...) is a negative lookahead that fails the match if its pattern matches:
    • 0+ - 1+ zeros
    • (?:\\.0*[1-9][0-9]*){3} - 3 consecutive occurrences of
    • \\. - a dot
    • 0* - 0+ zeros
    • [1-9] - a digit from 1 to 9
    • [0-9]* - any 0+ digits
    • $ - end of string.

Also, the octet regex now matches 0 , too:

  • (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) :
    • 25[0-5]| - 250 till 255
    • 2[0-4][0-9]| - 200 till 249
    • [01]?[0-9][0-9]? - 1 or 0 (optionally, 1 or 0 times) then any digit and then any 1 or 0 digits (an optional digit).

A Python demo :

import re

rx = """(?x)^   # start of string
         (?!    # start of the negative lookahead that fails the match if 
            0+(?:\.0*[1-9][0-9]*){3}$  # 0s appear only in the first octet
         )      # end of the lookahead
         (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)  # First octet regex
         (?:    # start of the non-capturing group
            \.  # a dot
            (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) # octet
         ){3}   # repeated 3 times
         $      # end of string
"""
lst = ['0.1.2.3','1.0.0.0','0.0.0.0']
for s in lst:
    m = re.match(rx, s)
    if m:
        print("{} matched!".format(s))
    else:
        print("{} did not match!".format(s))

Output:

0.1.2.3 did not match!
1.0.0.0 matched!
0.0.0.0 matched!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM