1 private final Pattern IPV6_PATTERN = Pattern.compile( 2 "^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|" + "^((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)$"); //正则表达式解析v6地址 3 4 private final Pattern IPV4_PATTERN = Pattern.compile( 5 "^((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]?)$"); //正则表达式解析v4地址 6 7 private final Pattern DOMAIN_NAME_PATTERN = Pattern.compile( 8 "^[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)+$"); //正则表达式解析域名地址 9 10 private boolean isIPv4Address(String address) { 11 return IPV4_PATTERN.matcher(address).matches(); // v4地址返回true 12 } 13 14 public boolean isDomainName(String uri) { 15 return DOMAIN_NAME_PATTERN.matcher(uri).matches(); // 域名地址返回true 16 }
应用下发URI链接给到应用或者系统,需要对该链接进行处理,判断下发的是哪种地址类型。如果下发的是域名地址或者是v4地址,都可以直接通过Uri来进行解析:
1 import java.util.regex.Pattern; 2 import android.net.Uri; 3 4 5 //传入的非Uri类型,而是String类型时,可以通过Uri.parse转换成Uri类型 6 Uri mUri = Uri.parse(strUrl); 7 String host = mUri.getHost();
如果下发的URI链接是一个v6类型的地址,那么很有可能会出现解析异常问题:
1 //传入如下地址链接时会解析出错 2 String strUrl = "http://[2433:8043:6c00:2:400::1234]:6666/?cancel_login=true"; 3 4 System.out.println("URI 的主机: " + host); 5 6 //输出结果 7 URI 的主机: [2433
改进方案:
将Uri改成URI
1 import java.net.URI; 2 3 try { 4 URI mUri = new URI(strUrl); 5 String host = mUri.getHost(); 6 System.out.println("test host == " + host); 7 } catch (Exception e) { 8 e.printStackTrace(); 9 }
现在能正常解析出v6地址,上述的执行结果:
test host == [2433:8043:6c00:2:400::1234]
现在就可以通过正则来确定是否是一个v6地址了。不过有一个问题,上面使用的判断v6的正则表达式是解析不了带有[]括号的地址的,需要改一下正则表达式:
1 private static final Pattern IPV6_PATTERN2 = Pattern.compile( 2 "^\\[?((?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?))\\]?$");
不过这样引入了一个问题,就是如果解析完成的host不带[]方括号的话,会解析失败,可以在判断v6的方法里加一个分支判断,判断是否以[开头,再决定使用哪一个正则表达式。
另外有一个问题,我用不同的编译器验证问题,发现有的使用Uri类可以正常解析下发的uri链接,但是有的不行,需要用URI类才可以:
1 import java.net.URI; 2 3 import android.net.Uri;
这个问题后面再研究吧,先记录一下。
浙公网安备 33010602011771号