你的位置:
问答吧
-> XML/HTML/CSS/JS
-> 问题详情
[正则表达式]求一个校验IPv6地址的正则表达式[已解决]
小弟用java做个正则表达式的校验,写了两天还是没有搞定,特来求助
IPv6使用8段十六进制的数加7个冒号表示的地址串 例如"1:22:333:4444:6:7:8"
但是因为太长了所以就采用了双冒号法表示.
例如:如下地址:
1111:22::3333:4:5
1:2:333::4444
目前的问题是当采用双冒号法的时候,因为长度和双冒号位置不定,一直校验不出.我试着写的一个目前只能校验处双冒号在最后位置的IPv6地址,如果每个位置都写一遍肯定可以实现,但是我想正则表达式肯定可以位置不敏感的.
贴上我的正则表达式实现:
复制内容到剪贴板
代码: String regHex = "(\\p{XDigit}{1,4})";
String regIPv6Full = "^(" + regHex + ":){7}" + regHex + "$";
String regIPv6AbWithoutColon = "^" + regHex + "?::" + regHex + "$" ;
String regIPv6AbWithColon = "^(" + regHex + ":){0,5}" + regHex + "::" + regHex + "$";
String regIPv6 = "^(" + regIPv6Full + ")|(" + regIPv6AbWithoutColon + ")|(" + regIPv6AbWithColon + ")$";运行后
复制内容到剪贴板
代码:regIPv6=
^(^((\p{XDigit}{1,4}):){7}(\p{XDigit}{1,4})$)|(^(\p{XDigit}{1,4})?::(\p{XDigit}{1,4})$)|(^((\p{XDigit}{1,4}):){0,5}(\p{XDigit}{1,4})::(\p{XDigit}{1,4})$)$附:
引用:有些类型的IPv6地址中包含了一长串0,为了进一步简化IPv6的地址表达,在一个以冒号十六进制表示法表示的IPv6地址中,如果几个连续位断的值都是0,那么这些0就可以简记为::,称为双冒号法
注意:在使用零压缩法时,不能把一个位段内部的有效0也压缩掉。例如:不能把FF02:30:0:0:0:0:0:5简写为FF02:3::5,而应该简写为FF02:30::5。零压缩法只能使用一次
作者: lanchong
发布时间: 2005-06-28
写了这么多其实主要是想问问
复制内容到剪贴板
代码: String regIPv6AbWithColon = "^(" + regHex + ":){0,5}" + regHex + "::" + regHex + "$";上面的代码是不是可以改成"::"双冒号的出现与冒号和十六进制数的出现次序不固定在最后,而是任意位置?
作者: lanchong
发布时间: 2005-06-28
为什么非要在一个正则里完成呢?
提示:您可以先修改部分代码再运行
作者: mozart0
发布时间: 2005-06-29
谢谢mozart0,这里是几个测试用例,我的正则最后两个例子跑不过,你写的那个有两个双冒号的也通不过.不过你给我了一个思路,我在修改中.
引用:为什么非要在一个正则里完成呢?不是非要在一个正则里面完成的,只是我刚学习写正则,不太熟悉规范.
复制内容到剪贴板
代码: (("FE06::1::2"),false); //只能用一次双冒号
(("10.2.3.5"),false); //没有冒号
(("00000:000000:0000::1"),false); //每段的长度不超过4
(("0000:0000:0000:0000:0000:0000:0000:0000:0000:1"),false); //总长度不超过39
(("JKLN:ssej::1"),false); //必须是十六进制的数字
(("12::45::1"),false); //双冒号必须只能出现一次
(("12::44:f:45::1"),false); //双冒号必须只能出现一次(不连续出现)
(("ABEF:452::FE10"),true); //正确的合法的IPv6
(("12::1"),true); //合理压缩
(("::1"),true); //双冒号压缩发
(("0000:0000:0000:0000:0000:0000:0000:0000"),true); //正确无压缩写法
(("::1:123:23"),true); //双冒号压缩发
(("123:45::ADC:6"),true); //双冒号位置不确定注意:这里的IPv6不考虑兼容地址形式.
作者: lanchong
发布时间: 2005-06-29
我比较笨,根本不知道ipv6应该怎么写……所以不知道怎么回答……楼主花个几分钟说明一下规则吧
作者: Sheneyan
发布时间: 2005-06-29
我们知道
IPv4的文本表示法:十进制点号表示法
IPv6的文本表示法:带有前导零和零压缩法的冒号十六进制格式
解释一下就是:
Format is x:x:x:x:x:x:x:x
x is a 16 bit hexadecimal field
FEDC:BA98:7654:3210:FEDC:BA98:7654:3210
Leading zeros in a field are optional
:: can be used to represent multiple groups of 16 bits of zero
:: can only be used once in an address
FF01:0:0:0:0:0:0:101 = FF01::101
0:0:0:0:0:0:0:1 = ::1
0:0:0:0:0:0:0:0 = ::
作者: lanchong
发布时间: 2005-06-29
没看清规则,不知道压缩法可用于首尾且只能用一次
提示:您可以先修改部分代码再运行
作者: mozart0
发布时间: 2005-06-29
非常感谢mozart0大虾,问题解决,下面附上我的Java实现,其中注释掉的是使用java内置类的另一个校验,他可以校验的非常全面准确,推荐使用,不过单单使用IPv6地址mozart0的js和我的这两个java方法已经够用了.
复制内容到剪贴板
代码: public boolean isIPv6(String address)
{
boolean result = false;
String regHex = "(\\p{XDigit}{1,4})";
String regIPv6Full = "^(" + regHex + ":){7}" + regHex + "$";
String regIPv6AbWithColon = "^(" + regHex + "(:|::)){0,6}" + regHex
+ "$";
String regIPv6AbStartWithDoubleColon = "^(" + "::(" + regHex
+ ":){0,5}" + regHex + ")$";
String regIPv6 = "^(" + regIPv6Full + ")|("
+ regIPv6AbStartWithDoubleColon + ")|(" + regIPv6AbWithColon
+ ")$";
System.out.println("regIPv6 =" + regIPv6);
if (address.indexOf(":") != -1)
{
if (address.length() <= 39)
{
String addressTemp = address;
int doubleColon = 0;
while (addressTemp.indexOf("::") != -1)
{
addressTemp = addressTemp.substring(addressTemp
.indexOf("::") + 2, addressTemp.length());
doubleColon++;
}
if (doubleColon <= 1)
{
result = address.matches(regIPv6);
}
}
}
// InetAddress addressIPv6 = null;
// Inet6Address IPv6 = null;
// Inet4Address IPv4 = null;
//
// try
// {
// addressIPv6 = InetAddress.getByName(address);
// }
// catch (UnknownHostException e)
// {
// loghelper.error("isIPv6", e.getMessage());
//
// e.printStackTrace();
// }
// if(addressIPv6 instanceof Inet6Address)
// {
// IPv6 = (Inet6Address) addressIPv6;
// System.out.println("addressIPv6 =" + addressIPv6.getHostAddress());
// result = true;
// }
// if(addressIPv6 instanceof Inet4Address)
// {
// IPv4 = (Inet4Address) addressIPv6;
// System.out.println("addressIPv4 =" + addressIPv6.getHostAddress());
// }
return result;
}
作者: lanchong
发布时间: 2005-06-29
贴一个最土的玩玩,土到可以改成C语言
Java好像很高级的说,偶不懂
改天我要能实现一个自己的正则系统,就可以自居大虾了
ps: IPv6,IP version 6?给整个银河系用?
提示:您可以先修改部分代码再运行
作者: mozart0
发布时间: 2005-06-29