Short RegExp solution


  • 8
    const ip4 = /^([1-9]\d{0,2}|0)(?:\.([1-9]\d{0,2}|0)){3}$/;
    const ip6 = /^([0-9a-fA-F]{1,4})(\:[0-9a-fA-F]{1,4}){7}$/;
    
    var validIPAddress = function(IP) {
        const isIp4 = ip4.exec(IP);
        if (isIp4 && isIp4.slice(1).every(d => parseInt(d, 10) < 256))
            return 'IPv4';
    
        const isIp6 = ip6.exec(IP);
        if (isIp6)
            return 'IPv6';
        
        return 'Neither';
    };
    

  • 0

    Not quite. For example claims that "1.1.1.1." is IPv4 and that "192.168.0.1" isn't. (fixed now)


  • 0

    @StefanPochmann You're right. I updated the regular expressions.


  • 0

    @dettier As an alternative to duplicating regex parts, you could add an extra . or : to the given IP string.


  • 7

    Just a version where I do the range check in the regex (and some other modifications):

    const ip4 = /^(\.(([1-9]?|1\d|2[0-4])\d|25[0-5])){4}$/;
    const ip6 = /^(:[0-9a-f]{1,4}){8}$/i;
    
    var validIPAddress = function(IP) {
        return ip4.exec('.' + IP) ? 'IPv4' : ip6.exec(':' + IP) ? 'IPv6' : 'Neither';
    };
    

  • 0

  • 2

    @dettier

    Thanks for sharing. Java version (using Stefan's idea):

    import java.util.regex.*;
    public class Solution {
        public String validIPAddress(String IP) {
            Pattern p1 = Pattern.compile("((([1-9]?|1\\d|2[0-4])\\d|25[0-5])\\.){3}(([1-9]?|1\\d|2[0-4])\\d|25[0-5])");
            Pattern p2 = Pattern.compile("(?i)([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}");
            
            Matcher m1 = p1.matcher(IP);
            if (m1.matches()) return "IPv4";
     
            Matcher m2 = p2.matcher(IP);
            if (m2.matches()) return "IPv6";
            
            return "Neither";
        }
    }

  • 0
    2

    Wow! Seems RE is really powerful!


  • 0
    H

    C++ version

        string validIPAddress(string IP) {
            regex ipv4("^([1-9]\\d{0,2}|0)(?:\\.([1-9]\\d{0,2}|0)){3}$");
            regex ipv6("^([0-9a-fA-F]{1,4})(\\:[0-9a-fA-F]{1,4}){7}$");
            
            smatch m;
            if (regex_match(IP, m, ipv4)) {
                for (auto& e: m) {
                    if (stoi(e) > 255) return "Neither"; 
                }
                return "IPv4";
            } else if (regex_match(IP, m, ipv6)) return "IPv6";
            return "Neither";
        }
    

  • 0

    Mixed Java, with simple regexp example:

    import java.util.regex.*;
    
    public class Solution {
        static Pattern ipv4Splitter = Pattern.compile("\\b\\.\\b"), ipv6Splitter = Pattern.compile("\\b:\\b");
        static Pattern ipv4Validator = Pattern.compile("0|[1-9]\\d{0,2}"), ipv6Validator = Pattern.compile("(?i)[\\da-f]{1,4}");
        public String validIPAddress(String ip) {
                 if (isValidIp(ipv4Splitter.split(ip), 4, this::isValidIpV4Chunk)) return "IPv4";
            else if (isValidIp(ipv6Splitter.split(ip), 8, this::isValidIpV6Chunk)) return "IPv6";
            else                                                                   return "Neither";
        }
        boolean isValidIp(String[] chunks, int expectedSize, Predicate<String> isValidChunk) {
            return (chunks.length == expectedSize) && Arrays.stream(chunks).allMatch(isValidChunk);
        }
        boolean isValidIpV4Chunk(String chunk) { return ipv4Validator.matcher(chunk).matches() && Integer.parseInt(chunk) <= 255; }
        boolean isValidIpV6Chunk(String chunk) { return ipv6Validator.matcher(chunk).matches(); }
    }
    

  • 0

    Python version:

    def validIPAddress(self, IP):
    	mtch = lambda pattern, s: re.match(pattern, s) != None
    	ipv4 = r'(1?[1-9]?\d|2[0-4]\d|25[0-5])(\.(1?[1-9]?\d|2[0-4]\d|25[0-5])){3}$'
    	ipv6 = r'([0-9A-Fa-f]{1,4})(:([0-9A-Fa-f]{1,4})){7}$'
    	return ['Neither', 'IPv4', 'IPv6'][mtch(ipv4, IP) + 2*mtch(ipv6, IP)]

Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.