Skip to content
Advertisement

How to match IP addresses in a comma-separated string

Code show as below, but there is a problem: “255.255.255.256” will be processed into “255.255.255.25”

import re

ip_pattern = re.compile(r"((25[0-5]|2[0-4]d|[01]?dd?).){3}(25[0-5]|2[0-4]d|[01]?dd?)")

def get_ip_by_regex(ip_str):
    """Match IP from the given text and return

    :param ip_str: like "255.255.255.255,255.255.255.256,260.255.255.255"
    :type ip_str: string
    :return: IP LIST ["255.255.255.255"]
    :rtype: list[string]
    """
    ret = []
    for match in ip_pattern.finditer(ip_str):
        ret.append(match.group())
    return ret

If I pass the 255.255.255.255,255.255.255.256,260.255.255.255 string I expect ["255.255.255.255"] as the results.

Advertisement

Answer

You want to implement comma boundaries, (?<![^,]) and (?![^,]):

ip_pattern = re.compile(r"(?<![^,])(?:(?:25[0-5]|2[0-4]d|[01]?dd?).){3}(?:25[0-5]|2[0-4]d|[01]?dd?)(?![^,])")

See the regex demo.

Details

  • (?<![^,]) – a negative lookbehind that matches a location not immediately preceded with a char other than a comma (i.e. there must be a comma or start of string immediately to the left of the current location)
  • (?![^,]) – a negative lookahead that matches a location not immediately followed with a char other than a comma (i.e. there must be a comma or end of string immediately to the right of the current location).

See the Python demo:

import re

ip_pattern = re.compile(r"(?<![^,])(?:(?:25[0-5]|2[0-4]d|[01]?dd?).){3}(?:25[0-5]|2[0-4]d|[01]?dd?)(?![^,])")

def get_ip_by_regex(ip_str):
    """Match IP from the given text and return

    :param ip_str: like "255.255.255.255,255.255.255.256,260.255.255.255"
    :type ip_str: string
    :return: IP LIST ["255.255.255.255"]
    :rtype: list[string]
    """
    return ip_pattern.findall(ip_str)

print(get_ip_by_regex('255.255.255.255,255.255.255.256,260.255.255.255'))
# => ['255.255.255.255']
Advertisement