PS*代码直接见第二部分:
一、进入正题前先说说JAVA正则表达式相关概念:
1、常用字符类:
[abc] == a||b||c [a-zA-Z] == 所有大小写字母中的任意一个 [0-9A-Za-z] == 任意一个字母或者数字
。。。。。。懒得打字了,直接上截图(Think in Java)
2、常用逻辑操作符、边界匹配符
3、量词(常用)
4、常用表达式以及意义:
? 示例:(X)? 0个或1个X
+ 示例:(X)+ 1个或多个X
* 示例:(X)* 0个或多个X
5、Pattern和Matcher类
这两个类上手使用比较简单,学习JAVA正则表达式建议仔细读一读
PS* 一定请注意 '?:' 非获取匹配,匹配冒号后的内容但不获取匹配结果,不进行存储供以后使用,在不想被捕获的时候使用 可以提高程序执行速度
比如有正则表达式,正则表达式开头出现的 '?:' 你可以把它理解成一个开关,写上它将不进行存储,可以提高执行速度,但是不能反向引用了;如果你只是想要匹配这个功能是可以大胆的写在开头的;但是如果你想要使用一些其它的中间结果,那么就不能使用这个开关了。
Pattern regexs = Pattern.compile("^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$");
二、JAVA正则表达式区分IPv4和IPv6地址
输入数据合法格式:
IPv4:唯一标准格式 -> 0-255.0-255.0-255.0-255
IPv6: 标 准 格 式 -> abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd 标准IPv6地址一共(8*4 + 7) 个字符
IPv6 压 缩 格 式 -> abcd::abcd:abcd:abcd:abcd
::abcd:abcd:abcd
abcd:abcd:abcd:abcd:abcd::
::1
::
IPv6压缩规则:至少一个全0块才可以压缩,并且只能压缩一次,存在多个全0块优先压缩更长的全0块;
我要反省,之前由于学艺不精,说错了一个问题,"至少两个全0块才可以压缩",这篇帖子似乎已经有一些人看过了。。。
我之前的说法可能误导了一些人。。。。emmm,不过还是要感谢评论里的大佬的指正;为体现我的诚意,我把测试代码给狠狠撸了一遍,,,,,这样看起来就很直观了。。。。。
--如果还有错误欢迎指正
import java.util.regex.Pattern;
import sun.net.util.IPAddressUtil;
import java.util.*;
public class JudgeIpAddress {
//标准IPv4地址的正则表达式:
private static final Pattern IPV4_REGEX =
Pattern.compile(
"^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$");
//无全0块,标准IPv6地址的正则表达式
private static final Pattern IPV6_STD_REGEX =
Pattern.compile(
"^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$");
//压缩正则表达式
private static final Pattern IPV6_COMPRESS_REGEX =
Pattern.compile(
"^(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)::((([0-9A-Fa-f]{1,4}:)*[0-9A-Fa-f]{1,4})?)$");
//判断是否为合法IPv4地址
public static boolean isIPv4Address(final String input){
return IPV4_REGEX.matcher(input).matches();
}
//以下为测试代码
//判断是否为合法IPv6地址
public static Map isIPv6Address(String input) {
Map resultMap = new HashMap();
// 8*4 位数字,加上七个: ipv6地址长度不可能超过39位
if(input.length()>39){//这里娶个巧,因为当压缩发生在ip地址的中间时,左右两边的非压缩段数尤其不好估计,
resultMap.put("value","false"); //起码几十种,不可能为了它写几十个正则吧?有便宜干嘛不占呢,嘿嘿
resultMap.put("method","长度非法");
}else if(IPV6_STD_REGEX.matcher(input).matches()){//标准格式判断
resultMap.put("value","true");
resultMap.put("method","标准格式");
}else if(IPV6_COMPRESS_REGEX.matcher(input).matches()){//压缩发生在IP地址内部;唯一确定内容,IP地址首尾无冒号 (:)
resultMap.put("value","true"); //压缩位置未知,压缩的连续全0块数量未知
resultMap.put("method","压缩格式");
}else{
resultMap.put("value","false");
resultMap.put("method","匹配错误");
}
return resultMap;
}
public static void main(String args[])
{
String JudegeType = "IPv6";
if(JudegeType.equals("IPv6")){
String[] ipAddrs = getParams();
for(String ipAddr:ipAddrs){
Map result = isIPv6Address(ipAddr);
boolean selfMethod = Boolean.valueOf(result.get("value").toString());
//官方判断IPv6地址方法
boolean sunMethod = IPAddressUtil.isIPv6LiteralAddress(ipAddr);
if(selfMethod==sunMethod){
System.out.print("##############自定义正则匹配结果与官方结果相同----判断一致!");
}else{
System.out.print("##############自定义正则匹配结果与官方结果相同----正则错误!");
}
System.out.print(" "+result.get("method"));
System.out.print(" IPAddressUtil:"+sunMethod);
if(selfMethod){
System.out.print(" IPv6合法");
}else{
System.out.print(" IPv6非法");
}
System.out.println(" "+ipAddr);
}
}else if(JudegeType.equals("IPv4")){
String[] examples = {
"192.168.1.1",
"192.0.1.1",
"999.168.1.1",
"192.168.1.1.0",
"192.168.256.1",
};
for(String example:examples){
System.out.print("IPAddressUtil:"+IPAddressUtil.isIPv4LiteralAddress(example));
System.out.print(" selfMethod:"+isIPv4Address(example));
if(IPAddressUtil.isIPv4LiteralAddress(example)==isIPv4Address(example)){
System.out.print("自定义正则判断无误!");
}else{
System.out.print("自定义正则判断失准!");
}
System.out.println(" "+example);
}
}
}
//测试数据
public static String[] getParams(){
return new String[]{
"::",
"a:b:c:D:e:f:f:F",
"a:b:c:D:G:f:f:F",
"a:b:c:D:g:f:f:F",
"fe80:1295:8030:49ec::1fc6:57fa:2222:0000",
"fe80:1295:8030:49ec:1fc6:57fa:0000:",
":1295:8030:49ec:1fc6:57fa:0000:0000",
"fe80:1295:8030:1fc6:57fa:0000:0000",
"fe80:1295:8030:49ec:1fc6:57fa::0000",
"fe80::0000",
"fe80::",
"::0000",
"fe80:1295:8030:0000",
"fe80:1295:8030::0000:0000",
"fe80:1295:8030:49ec:1fc6:57fa:::0000:0000:0000:0000:0000:0000:0000:0000",
"::8030:49ec:1fc6:57fa:0000:0000:0000:0000:0000:0000",
"fe80:1295::49ec:1fc6:57fa:0000:0000",
"fe80:1295:8030:49ec::1fc6:57fa:0000:0000:0000:0000:0000:0000:0000:0000:0000",
"fe80::1295:8030:49ec:1fc6:57fa:0000:0000:0000",
"fe80:1295:8030:49ec::1fc6:57fa:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000",
"fe80:1295:8030:49ec:1fc6::57fa:0000:0000:0000:0000:0000",
"fe80:1295:8030:49ec:1fc6:57fa::0000:0000:0000:0000:0000",
"fe80:1295:8030:49ec:1fc6:57fa:0000::0000:0000:0000:0000",
"fe80:0000:0000:0000:1fc6:57fa::1241:0000:0000:0000:0000:0000:0000",
"::fe80:1295:8030:49ec:1fc6:57fa:2222:0000",
":1295:8030:49ec:1fc6:57fa:2222:0000",
"fe80:1295:8030:49ec:1fc6:57fa:2222:0000:",
"fe80:1295:8030:49ec:1fc6:57fa:2222:0000::",
"::fe80:1295:8030:49ec:1fc6:57fa:2222:0000",
"fe80:1295:8030:49ec:1fc6:57fa:2222:",
":1295:8030:49ec:1fc6:57fa:2222:0000",
"fe80:1295:8030:49ec:1fc6:57fa::",
"::fe80:1295:8030:49ec:1fc6:57fa",
"fe80:1295:8030:49ec:1fc6:57fa:a::",
"::b:fe80:1295:8030:49ec:1fc6:57fa",
"fe80:1295:8030:49ec:1fc6:57fa:2222::",
"::1295:8030:49ec:1fc6:57fa:2222:0000",
"::8030:49ec:1fc6:57fa:2222:0000",
"fe80:1295:8030:49ec:1fc6:57fa:0000:0000"
};
}
}