在Java中validationIPv4string

Bellow方法validationstring是否正确。如果IPv4地址有效,则返回true。 任何正则expression式和优雅的改进将非常感激:

public static boolean validIP(String ip) { if (ip == null || ip.isEmpty()) return false; ip = ip.trim(); if ((ip.length() < 6) & (ip.length() > 15)) return false; try { Pattern pattern = Pattern.compile("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"); Matcher matcher = pattern.matcher(ip); return matcher.matches(); } catch (PatternSyntaxException ex) { return false; } } 

这是一个容易阅读,效率稍低的方法,你可以去做。

 public static boolean validIP (String ip) { try { if ( ip == null || ip.isEmpty() ) { return false; } String[] parts = ip.split( "\\." ); if ( parts.length != 4 ) { return false; } for ( String s : parts ) { int i = Integer.parseInt( s ); if ( (i < 0) || (i > 255) ) { return false; } } if ( ip.endsWith(".") ) { return false; } return true; } catch (NumberFormatException nfe) { return false; } } 

更新: Commons-HttpClient及其后继HttpComponents-HttpClient已采用此function。 你可以像这样使用它的这个版本: InetAddressUtils.isIPv4Address(Str)


Apache Commons Validator的开发版本有一个InetAddressValidator类,它有一个isValidInet4Address(String)方法来检查给定的String是否是有效的IPv4地址。

源代码可以从存储库中查看,所以如果您觉得有任何改进,可以提供一些改进的想法。

快速浏览提供的代码,可以看出您的方法在每次调用方法时都编译一个Pattern 。 我将这个Pattern类移出到一个static字段,以避免在每个调用上花费昂贵的模式编译过程。

如果你想使用支持IPv4和IPv6支持的发行版的库,你可以使用Guava

 boolean isValid = InetAddresses.isInetAddress("1.2.3.4"); 

这里有一个解决scheme,它使用Java 8stream来检查地址是否包含0到255之间的4个数字,用点分隔:

 public class IpValidation { /** * Check that a string represents a decimal number * @param string The string to check * @return true if string consists of only numbers without leading zeroes, false otherwise */ public static boolean isDecimal(String string) { if (string.startsWith("0")) { if (string.length() == 1) { // "0" return true; } // The string has a leading zero but is not "0" return false; } for(char c : string.toCharArray()) { if(c < '0' || c > '9') { return false; } } return true; } public static boolean isIp(String string) { String[] parts = string.split("\\.", -1); return parts.length == 4 // 4 parts && Arrays.stream(parts) .filter(IpValidation::isDecimal) // Only decimal numbers .map(Integer::parseInt) .filter(i -> i <= 255 && i >= 0) // Must be inside [0, 255] .count() == 4; // 4 numerical parts inside [0, 255] } } 

如果您不介意在www.example.com等无效IP地址上使用DNSparsing,则可以使用InetAddress方法来检查:

 public static final boolean checkIPv4(final String ip) { boolean isIPv4; try { final InetAddress inet = InetAddress.getByName(ip); isIPv4 = inet.getHostAddress().equals(ip) && inet instanceof Inet4Address; } catch (final UnknownHostException e) { isIPv4 = false; } return isIPv4; } 

该方法检查它是否是Inet4Address的实例,以及参数是否是ip-address而不是主机名。 如果您希望有很多主机名作为参数,请注意,此实现使用DNS来尝试parsing它。 这可能是一个性能问题。

否则,你可以有一个峰值到boolean sun.net.util.IPAddressUtil.isIPv4LiteralAddress(String src)如何在那里分析string的IPv4检查。

从这里find正则expression式的例子

 package com.mkyong.regex; import java.util.regex.Matcher; import java.util.regex.Pattern; public class IPAddressValidator{ private Pattern pattern; private Matcher matcher; private static final String IPADDRESS_PATTERN = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"; public IPAddressValidator(){ pattern = Pattern.compile(IPADDRESS_PATTERN); } /** * Validate ip address with regular expression * @param ip ip address for validation * @return true valid ip address, false invalid ip address */ public boolean validate(final String ip){ matcher = pattern.matcher(ip); return matcher.matches(); } } 

在认为这个解决scheme是相当优雅的,虽然它需要一分钟的时间来理解。

基本的想法是采取一个子string,并validation它。
请注意,我切换x和y,因为一个子string的开始将始终是最后一个加1的结尾。

这个解决scheme比正则expression式快20倍,比分裂快2倍。

 public static boolean validIP(String ip) { if(ip == null || ip.length() < 7 || ip.length() > 15) return false; try { int x = 0; int y = ip.indexOf('.'); if (y == -1 || ip.charAt(x) == '-' || Integer.parseInt(ip.substring(x, y)) > 255) return false; x = ip.indexOf('.', ++y); if (x == -1 || ip.charAt(y) == '-' || Integer.parseInt(ip.substring(y, x)) > 255) return false; y = ip.indexOf('.', ++x); return !(y == -1 || ip.charAt(x) == '-' || Integer.parseInt(ip.substring(x, y)) > 255 || ip.charAt(++y) == '-' || Integer.parseInt(ip.substring(y, ip.length())) > 255 || ip.charAt(ip.length()-1) == '.'); } catch (NumberFormatException e) { return false; } } 

如果你知道你会有很多错误的IP地址,请考虑在第一个if下面添加下面的代码。 这将使代码慢1.5倍,但在出现错误的情况下提高700倍

  for (int i = 0; i < ip.length(); i++) { if (!Character.isDigit(ip.charAt(i)) && ip.charAt(i) != '.') return false; } 

如果您在问题中使用代码,则需要更改该行:

 if ((ip.length() < 6) & (ip.length() > 15)) return false; 

 if ((ip.length() <= 6) || (ip.length() > 15)) return false; 

尝试使用以下regrex for IPv4

 String ip4Regex="^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})(\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})){3}$"; 

希望能帮助到你 :)

我认为正确的方法是build立一个IPAddress类,并通过给它一个ip地址的string表示来实例化它。

通过这种方式,您可以将不同的validation步骤分解为实例方法,并将问题分离出来。

例如,这里通常是它自己的方法,简单的调用isEmpty

 return (ip == null || ip.isEmpty()); 

另外这应该是一个单独的方法,你可以调用这个hasProbableLength

 ip = ip.trim(); return ((ip.length() < 6) & (ip.length() > 15)); 

这里有很多事情正在进行。 我会试图打破这个,也许试图完全跳过正则expression式。

 try { Pattern pattern = Pattern.compile("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"); Matcher matcher = pattern.matcher(ip); return matcher.matches(); } catch (PatternSyntaxException ex) { return false; } 

我首先将string分成几个小圆点,然后看到我正好有四个小组。 调用这个方法divideIntoGroups

然后,我将validation每个组是0到255之间的值。调用此方法validateGroups

现在你有了这个,如果你想扩展这个类来查找IP是本地主机还是广播地址,那么这样做很容易。 这是什么分离关注给你。

在validationIP地址string时,您也可以确切地知道哪个validation规则被破坏了。 正则expression式不会的东西。

最简单的方法,我发现检查给定的ip是正确的在ipv4是使用commons-validator-1.4.0.jar有类: –

 org.apache.commons.validator.routines.InetAddressValidator 

InetAddressValidator

例如

 InetAddressValidator inetValidator = InetAddressValidator.getInstance(); inetValidator.isValidInet4Address(yourIPAddress); 

它使用这个简单的正则expression式:

  "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$"; 

大部分答案(除了Michael Konietzka的答案)都是错误的:例如,10.8是一个有效的IP4地址(10.0.0.8的简写)。

请参阅Java规范中IP地址的文本表示 。

在参考文献中可以看到,为了检查数字表示,可以有1到4个部分,并且在每种情况下对部件应用不同的限制。

我会build议使用你正在开发的平台/框架上有什么。

如果没有什么你认为足够好,那么你可能只是想要添加一个编译正则expression式到一个辅助类。 例如,下面是Android框架的function:

 public static final Pattern IP_ADDRESS = Pattern.compile( "((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]" + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]" + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}" + "|[1-9][0-9]|[0-9]))"); 
 boolean isValid = inetAddressValidator.isValid(hostName) || hostName.equalsIgnoreCase("localhost"); 

与coobird相同的答案。 只需将本地主机添加到该语句。 大部分环境都将'localhost'作为有效的主机名。 这不是一个ipv4格式,但应包括考虑有效性。

IPAddress Java库将做到这一点。 javadoc可在链接中find。 免责声明:我是项目经理。

这个库透明地支持IPv4和IPv6,所以validation或者工作在下面,它也支持CIDR前缀长度的IPC4地址。 它支持更多不寻常的格式,如inet_aton(例如10.8在另一个答案中提到)

validation地址是否有效:

  String str = "1.2.3.4"; IPAddressString addrString = new IPAddressString(str); try { IPAddress addr = addrString.toAddress(); ... } catch(IPAddressStringException e) { //e.getMessage provides validation issue } 
 public static boolean ipv4Check(String ipAddress){ try{ if(ipAddress!=null && !ipAddress.isEmpty()){ String [] ip = ipAddress.split("\\."); if(ip.length!=4) return false; for(int i=0;i<=ip.length-1;i++){ int j=Integer.parseInt(ip[i]); if(j<0 || j>255){ return false; } } if ( ipAddress.endsWith(".") ) { return false; } if ( ipAddress.startsWith(".") ) { return false; } } return true; } catch (NumberFormatException ex) { return false; } }