验证Java中的IPv4字符串

验证Java中的IPv4字符串,java,string,validation,ip,Java,String,Validation,Ip,Bellow方法正在验证字符串是否为正确的IPv4地址。如果字符串有效,则返回true。如对正则表达式和优雅性有任何改进,将不胜感激: public static boolean validIP(String ip) { if (ip == null || ip.isEmpty()) return false; ip = ip.trim(); if ((ip.length() < 6) & (ip.length() > 15)) return fals

Bellow方法正在验证字符串是否为正确的IPv4地址。如果字符串有效,则返回true。如对正则表达式和优雅性有任何改进,将不胜感激:

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;
    }
}
公共静态布尔值(字符串ip){
if(ip==null | | ip.isEmpty())返回false;
ip=ip.trim();
if((ip.length()<6)和(ip.length()>15))返回false;
试一试{
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]?)$”;
匹配器匹配器=模式匹配器(ip);
返回matcher.matches();
}捕获(模式语法异常){
返回false;
}
}

更新:Commons HttpClient及其后续HttpComponents HttpClient已采用此功能。您可以像这样使用此版本:
InetAddressUtils.isIPv4Address(Str)


的开发版本有一个类,该类有一个方法来执行检查,以查看给定的
字符串
是否是有效的IPv4地址

可以从存储库中查看,因此,如果您觉得有改进的想法,可能会提供一些想法


快速浏览一下提供的代码,就会发现您的方法在每次调用该方法时都编译了一个
模式。我会将
模式
类移出到
静态
字段中,以避免每次调用时花费高昂的模式编译过程。

如果您不介意对无效ip地址(如
www.example.com
)使用dns解析,您可以使用以下方法检查:

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地址而不是主机名。 如果您希望有很多主机名作为参数,请注意此实现使用DNS来尝试解析它。这可能是性能问题

否则,你可以有一个峰值进入
boolean sun.net.util.IPAddressUtil.isIPv4LiteralAddress(字符串src)
如何解析该字符串以进行IPv4检查。

以下是一种更容易阅读、效率稍低的方法

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;
    }
}
公共静态布尔值(字符串ip){
试一试{
if(ip==null | | ip.isEmpty()){
返回false;
}
String[]parts=ip.split(“\\”);
如果(零件长度!=4){
返回false;
}
用于(字符串s:零件){
int i=整数.parseInt(s);
如果((i<0)|(i>255)){
返回false;
}
}
如果(ip.endsWith(“.”){
返回false;
}
返回true;
}捕获(NumberFormatException nfe){
返回false;
}
}

如果您想使用一个版本同时支持IPv4和IPv6的库,您可以使用


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

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

if((ip.length()15))返回false;
从中查找正则表达式示例


下面是一个解决方案,它使用Java 8流检查地址是否由0到255(含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) {
        // Check whether string has a leading zero but is not "0"
        if (string.startsWith("0")) {
            return string.length() == 1;
        }
        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]
    }
}
公共类验证{
/**
*检查字符串是否表示十进制数
*@param string要检查的字符串
*@return true,如果字符串只包含数字而不包含前导零,则返回false
*/
公共静态布尔值isDecimal(字符串){
//检查字符串是否有前导零,但不是“0”
if(string.startsWith(“0”)){
返回字符串。length()==1;
}
for(char c:string.toCharArray()){
如果(c<'0'| c>'9'){
返回false;
}
}
返回true;
}
公共静态布尔isIp(字符串){
String[]parts=String.split(“\\.”,-1);
返回零件。长度==4//4个零件
&&数组.流(部分)
.filter(IpValidation::isDecimal)//仅十进制数
.map(整数::parseInt)
.filter(i->i=0)//必须在[0255]内
.count()==4;//[0,255]内有4个数字部分
}
}

在本文中,我认为这个解决方案非常优雅,尽管理解它需要一分钟的时间

基本思想是获取一个子字符串,然后对其进行验证。
请注意,我切换x和y,因为子字符串的开头总是最后一个子字符串的结尾加上1

此解决方案比正则表达式变体快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(ip==null | | ip.length()<7 | | ip.length()>15)返回false;
试一试{
int x=0;
int y=ip.indexOf('.');
如果(y=-1 | | ip.charAt(x)='-'| | Integer.parseInt(ip.substring(x,y))>255)返回false;
x=ip.indexOf('.',++y);
如果(x=-1 | | ip.charAt(y)='-'| | Integer.parseInt(ip.substring(y,x))>255)返回false;
y=ip.indexOf('.',++x);
返回!(y==-1||
ip.charAt(x)='-'||
整数.parseInt(ip.substring(x,y))>255||
ip.字符(++y)='-'||
Integer.parseInt(ip.substring(y,ip.length())>255||
ip.charAt(ip.length()-1)='.');
}捕获(数字格式){
返回false;
}
}

如果你知道你会有很多错误,请考虑在下面的第一个例子中添加下面的代码。这将使代码速度降低1.5倍,但如果出现错误,将代码速度提高700倍

    for (int i = 0; i < ip.length(); i++) {
        if (!Character.isDigit(ip.charAt(i)) && ip.charAt(i) != '.') return false;
    }
for(int i=0;i
    for (int i = 0; i < ip.length(); i++) {
        if (!Character.isDigit(ip.charAt(i)) && ip.charAt(i) != '.') return false;
    }
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}$";
return (ip == null || ip.isEmpty());
ip = ip.trim();
return ((ip.length() < 6) & (ip.length() > 15));
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;
}
org.apache.commons.validator.routines.InetAddressValidator
InetAddressValidator inetValidator = InetAddressValidator.getInstance();
inetValidator.isValidInet4Address(yourIPAddress);
  "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$";
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");
    String str = "1.2.3.4";
    IPAddressString addrString = new IPAddressString(str);
    try {
         IPAddress addr = addrString.toAddress();
         ...
    } catch(AddressStringException 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;
    }       
}

boolean isIPv4Address(String inputString) {
    String[] splitString = inputString.split("[.]");
    if (splitString.length > 4) {
        return false;
    }
    for (String string : splitString) {
        if (string.isEmpty()) {
            return false;
        }
        if (!string.matches("[0-9]{1,3}")) {
            return false;
        }
        int number = Integer.parseInt(string);
        if (!(number >= 0 && number <= 255)) {
            return false;
        }
    }
    return true;
}