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']