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;
}
}
答案 0 :(得分:52)
这是一种更容易阅读,效率稍低的方式。
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;
}
}
答案 1 :(得分:45)
UPDATE: Commons-HttpClient及其后继者HttpComponents-HttpClient已采用此功能。您可以像这样使用此版本:InetAddressUtils.isIPv4Address(Str)
。
Apache Commons Validator的开发版本有一个InetAddressValidator
类,其中有一个isValidInet4Address(String)
方法可以检查给定的String
是否为有效的IPv4地址。< / p>
可以从存储库中查看source code,这样如果您觉得有任何改进,可能会提供一些改进的想法。
快速浏览一下提供的代码,可以看出您的方法是在每次调用方法时编译Pattern
。我会将Pattern
类移到static
字段,以避免每次调用都进行昂贵的模式编译过程。
答案 2 :(得分:21)
如果要使用具有支持IPv4和IPv6支持的已发布版本的库,可以使用Guava
boolean isValid = InetAddresses.isInetAddress("1.2.3.4");
答案 3 :(得分:15)
这是一个使用Java 8流来检查地址是否包含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]
}
}
答案 4 :(得分:14)
如果您不介意在www.example.com
这样的无效IP地址上使用DNS解析,则可以使用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尝试解析它。这可能是一个性能问题。
否则你可以有一个高峰
boolean sun.net.util.IPAddressUtil.isIPv4LiteralAddress(String src)
如何在那里解析String以进行IPv4检查。
答案 5 :(得分:7)
从this
中查找正则表达式示例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();
}
}
答案 6 :(得分:5)
认为这个解决方案非常优雅,虽然需要花一点时间来理解它。
基本的想法是取一个子串而不是验证它。
请注意我切换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下面添加以下代码。这将使代码慢1.5倍但如果出现错误则将其提高700倍
for (int i = 0; i < ip.length(); i++) {
if (!Character.isDigit(ip.charAt(i)) && ip.charAt(i) != '.') return false;
}
答案 7 :(得分:4)
如果您使用问题中的代码,则需要更改行:
if ((ip.length() < 6) & (ip.length() > 15)) return false;
到
if ((ip.length() <= 6) || (ip.length() > 15)) return false;
答案 8 :(得分:4)
大多数答案(Michael Konietzka除外)都是错误的:例如,10.8是一个有效的IP4地址(10.0.0.8的简写)。
请参阅Java规范中的Textual representation of IP addresses。
从参考文献中可以看出,为了检查数字表示,可能有1到4个部分,并且在每种情况下对部件的不同限制都适用。
答案 9 :(得分:3)
尝试使用以下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}$";
希望它有所帮助:)
答案 10 :(得分:3)
我认为正确的方法是构建一个IPAddress
类,并通过给它一个ip地址的字符串表示来实现它。
通过这种方式,您可以将不同的验证步骤拆分为实例方法,并获得一些separation of concern。
例如,这里通常是它自己的方法,只需调用它isEmpty
:
return (ip == null || ip.isEmpty());
此外,这应该是一个单独的方法,您可以将其称为hasProbableLength
。
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;
}
我首先将字符串分成点,然后看到我恰好有四组。请调用此方法divideIntoGroups
然后我会验证每个组是否为0到255之间的值。调用此方法validateGroups
现在您已经拥有了这个,如果您想扩展此类以查找IP是localhost还是广播地址,那么这很容易实现。这是separation of concerns给你的。
您还可以确切地确定验证IP地址字符串中的哪一个验证规则已被破坏。正则表达式不会的东西。
答案 11 :(得分:2)
我发现在ipv4中正确检查给定ip的最简单的方法是使用commons-validator-1.4.0.jar有类: -
org.apache.commons.validator.routines.InetAddressValidator
E.g。
InetAddressValidator inetValidator = InetAddressValidator.getInstance();
inetValidator.isValidInet4Address(yourIPAddress);
使用这个简单的正则表达式: -
"^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$";
答案 12 :(得分:1)
我建议您使用您正在开发的平台/框架上提供的内容。
如果您认为没有什么是好的,那么您可能只想将编译的正则表达式添加到帮助程序类中。例如,here&#39} Android框架是如何做到的:
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]))");
答案 13 :(得分:1)
boolean isValid = inetAddressValidator.isValid(hostName) || hostName.equalsIgnoreCase("localhost");
与coobird相同的答案。只需将localhost添加到语句中即可。大多数环境将“localhost”作为有效的主机名。它不是ipv4格式,但应包括在内以考虑有效性。
答案 14 :(得分:1)
The IPAddress Java library会这样做。链接中提供了javadoc。免责声明:我是项目经理。
该库透明地支持IPv4和IPv6,因此验证在下面的工作方式相同,并且它也支持CIDR前缀长度的IPC4地址。它支持更不寻常的格式,如inet_aton(例如10.8在另一个答案中提到)
验证地址是否有效:
String str = "1.2.3.4";
IPAddressString addrString = new IPAddressString(str);
try {
IPAddress addr = addrString.toAddress();
...
} catch(AddressStringException e) {
//e.getMessage provides validation issue
}
答案 15 :(得分:1)
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;
}
}
答案 16 :(得分:1)
对你有用,
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;
}