# https://leetcode.com/problems/validate-ip-address/
    
# Write a function to check whether an input string is a valid IPv4 address or IPv6 address or neither.

# IPv4 addresses are canonically represented in dot-decimal notation, which consists of four decimal numbers, each ranging from 0 to 255, separated by dots ("."), e.g.,172.16.254.1;

# Besides, leading zeros in the IPv4 is invalid. For example, the address 172.16.254.01 is invalid.

# IPv6 addresses are represented as eight groups of four hexadecimal digits, each group representing 16 bits. The groups are separated by colons (":"). For example, the address 2001:0db8:85a3:0000:0000:8a2e:0370:7334 is a valid one. Also, we could omit some leading zeros among four hexadecimal digits and some low-case characters in the address to upper-case ones, so 2001:db8:85a3:0:0:8A2E:0370:7334 is also a valid IPv6 address(Omit leading zeros and using upper cases).

# However, we don't replace a consecutive group of zero value with a single empty group using two consecutive colons (::) to pursue simplicity. For example, 2001:0db8:85a3::8A2E:0370:7334 is an invalid IPv6 address.

# Besides, extra leading zeros in the IPv6 is also invalid. For example, the address 02001:0db8:85a3:0000:0000:8a2e:0370:7334 is invalid.

class Solution:
    def validIPAddress(self, IP: str) -> str:
        
        ipv4, ipv6 = IP.split("."), IP.split(":")
        ipv4_cnt, ipv6_cnt = len(ipv4), len(ipv6)        
        
        if ipv4_cnt == 4:
            ipv4_flag = True
            for s in ipv4:
                n = len(s)
                if not s or (n > 1 and s[0] == '0') or re.search(r'[^\d-]',s) or not (0 <= int(s) <= 255):
                    ipv4_flag = False
                    break
            if ipv4_flag:
                return 'IPv4'
        elif ipv6_cnt == 8:
            ipv6_flag = True
            for s in ipv6:
                if not re.match(r'^[0-9a-fA-F]{1,4}$', s):
                    ipv6_flag = False
                    break
            if ipv6_flag:
                return 'IPv6'
        return 'Neither'