A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

10黑马币
本帖最后由 cat73 于 2015-5-3 22:05 编辑

之前有一个类似的题目→(传送门)
事情是酱紫的,我自己写了个匹配IP地址的正则表达式,但是仍然有一些缺陷,以及还想要一丢丢增强,于是提出两个要求。
只需要完成任何一个,10个黑马币就是你的啦,最多可获得25黑马币喵~~

我自己写的正则表达式如下:↓
  1. (([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])
复制代码

比如我拿以下IP做测试:↓
  1. 64.233.162.85|64.233.162.84|64.233.179.143|80.64.175.109|64.233.178.122
  2. 210.153.73.113|64.233.161.96|173.194.204.166|210.245.14.256
  3. 256.245.14.255|192.168.1.1|10.141.137.8
复制代码

匹配结果如下图:↓



两个要求分别如下:↓
  1. 1.看到9跟10号结果没?因为出现了256,超出了正常IP的范围,因此这不是一个合格的IP地址,但是现在的匹配结果会将其砍掉一部分后作为结果输出,如果能修改下正则过滤掉这种结果就好了。
  2. 2.注意11跟12号结果,这个是功能增强性的要求,我想直接使用正则表达式过滤某个IP段,比如192.x.x.x、10.x.x.x、172.x.x.x这类,要求写出可以同时过滤多个IP段的正则表达式(要求能轻松增加某段IP)。
  3. 加分题:过滤特定IP地址,如192.168.1.1、172.10.0.17、10.141.137.8这几个IP不要出现在结果中(要求能轻松增加某个IP)。
复制代码

限制:↓
使用纯正则表达式,禁止插入任何语言的程序代码。
也就是说你只能对我的正则表达式进行修改来作为答案,或者自己重写一份正则表达式。

答案审核的问题:↓
做出来任何一个即可获得10黑马币,两个同时做出将给予20黑马币的奖励,做出加分题的额外给予5黑马币奖励,以最早提交答案的为准。
至少每天来查看一次,采纳最佳答案后会取消回帖仅作者可见的设置。

经过简单改进后的答案:↓
  1. (?<!\d)(?!((10|172|192\.168).+|210\.153\.73\.113|64\.233\.162\.84))(([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])(\.([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])){3})(?!\d)
复制代码
解释下这段正则:
(?<!\d)(?!((10|172|192\.168).+|210\.153\.73\.113|64\.233\.162\.84))(([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])(\.([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])){3})(?!\d)
比最佳回复里的答案的优点是结构更简单,增加不需要匹配的IP更容易。
绿色:x.x.x.256、256.x.x.x这种,不会砍掉一部分之后作为匹配结果
蓝色:例外情况,不被匹配的IP或IP段
红色:匹配标准IP地址的部分,用于匹配一个0.0.0.0~255.255.255.255之间的标准IPv4地址

如果你用JavaScript,可以删掉前面的绿色部分或者替换为\b。
删掉会导致256.x.x.x被砍掉2后匹配出来。
换\b会导致例如aaa12.34.56.78这种情况下,无法匹配到这个IP。
或者改用(?!\d)[^\d],剩下的作为子匹配1,取出子匹配1来当结果用。

解释下蓝色部分:
(?!((10|172|192\.168).+|210\.153\.73\.113|64\.233\.162\.84))
绿色:过滤10.x.x.x、172.x.x.x的IP地址
红色:过滤192.168.x.x的IP地址,192.168.1.x跟这个类似
蓝色:过滤特定IP地址



最佳答案

查看完整内容

标准答案如下(第一题第二题加分题同时完成): 解释下这段正则 \b[/backcolor](?!(210\.153\.73\.113|64\.233\.162\.84))[/backcolor]((?!(192|10|172))[/backcolor]([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])(\.([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])){3}[/backcolor])\b[/backcolor] 绿色部分是第一题:x.x.x.256、256.x.x.x这种,不会砍掉一部分之后作为匹配结果 蓝色部分是第二题:不匹配192.x.x.x、10.x.x.x、172.x.x.x的IP地址 紫色 ...

22 个回复

倒序浏览
本帖最后由 咪咪大人 于 2015-5-3 20:13 编辑

标准答案如下(第一题第二题加分题同时完成):
  1. \b(?!(210\.153\.73\.113|64\.233\.162\.84))((?!(192|10|172))([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])(\.([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])){3})\b
复制代码

解释下这段正则
\b(?!(210\.153\.73\.113|64\.233\.162\.84))((?!(192|10|172))([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])(\.([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])){3})\b

绿色部分是第一题:x.x.x.256、256.x.x.x这种,不会砍掉一部分之后作为匹配结果
蓝色部分是第二题:不匹配192.x.x.x、10.x.x.x、172.x.x.x的IP地址
紫色部分是加分题:不匹配特定的IP地址
红色部分是匹配标准IP地址的部分,用于匹配一个0.0.0.0~255.255.255.255之间的标准IPv4地址

点评

顺道记一下 匹配标准IP地址且四位相同的正则 \b([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])(\.\1){3}\b  发表于 2015-5-3 20:01
因为最后自己做出来了,就用小号提交了,就不加悬赏积分数了- -  发表于 2015-5-3 19:58
回复 使用道具 举报
又是你啊
回复 使用道具 举报
我觉得做不出来,210.245.14.256和210.245.14.25匹配不出来
他哪知道你是要匹配3位数还是二位数
我觉得全部换成等长的四组三位数111.111.111.111 ,像这样才能匹配出来,

而且,你表达式 [1-9]?\d 是有问题的,像 0.0.0.0也能通过

ps:如果真做出来了,记得提醒哈我啊??

点评

其实我可以做到过滤192,也就是第二题的要求,但是结果它会砍掉1,剩下92,这样还是不行。。。  发表于 2015-5-3 10:35
0.0.0.0是一个标准IP地址,所以说这并不是一个问题,以及你说的等长问题,如果问题那么简单,我还要来这里提问么?  发表于 2015-5-3 00:05
回复 使用道具 举报
major2015 发表于 2015-5-2 22:45
我觉得做不出来,210.245.14.256和210.245.14.25匹配不出来
他哪知道你是要匹配3位数还是二位数
我觉得全部 ...

... 你知道,混这个论坛的大部分是入门的,而且你在java版提问regex。。。

点评

因为没有正则表达式版块啊,Java中也可以用正则表达式嘛,这也不算超出Java版块的范围嘛。  发表于 2015-5-3 09:38
回复 使用道具 举报
你要先想想怎么分别210.245.14.256和210.245.14.25
也就是,怎么判断是用三位数还是用二位数匹配,
貌似正则做不到字符串长度判断吧

点评

有人做出来了 在两边加\b即可 不过他还改写了我的正则 又引入了新的Bug 因此不作为答案采纳  发表于 2015-5-3 16:19
还是以前的问题- - 怎么同时匹配多个字符。。。  发表于 2015-5-3 10:57
回复 使用道具 举报
cat73 黑马帝 2015-5-3 11:04:10
7#
其实这个问题是我在写一个项目的时候用到的- -
部分代码:↓
  1. <script type="text/javascript">
  2.     function conversionFormat(sf, tf, ss) {
  3.         if( sf == tf ) {
  4.             return ss;
  5.         }

  6.         var ipList;
  7.         if( sf == 1 ) {
  8.             ipList = ss.split("|");
  9.         } else if( sf == 2 ) {
  10.             ipList = ss.split("\n");
  11.         } else if( sf == 3 ) {
  12.             ipList = ss.match(/(([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])/g);
  13.         }

  14.         var result;
  15.         if( tf == 1 ) {
  16.             result = '';
  17.             for(var id in ipList) {
  18.                 result += ipList[id] + '|';
  19.             }
  20.             result = result.substr(0, result.length - 1);
  21.         } else if( tf == 2 ) {
  22.             result = '';
  23.             for(var id in ipList) {
  24.                 result += ipList[id] + '\n';
  25.             }
  26.         }

  27.         return result;
  28.     }
  29. </script>
复制代码

至于上面提到的问题,其实并不是项目的需求,只是想过滤的更好点而已- -
然后就来这里发问题了- -
回复 使用道具 举报
本帖最后由 星云 于 2015-5-3 15:04 编辑

正则表达式如下:
  1. \b(([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5])\b
复制代码
测试数据
d:\Test.txt内容如下:
  1. 64.233.162.85|64.233.162.84|64.233.179.143|80.64.175.109|64.233.178.122
  2. 210.153.73.113|64.233.161.96|173.194.204.166|210.245.14.256
  3. 256.245.14.255|192.168.1.1|10.141.137.8
复制代码
测试Demo:
IPRegexTestDemo.java
  1. import java.io.BufferedReader;
  2. import java.io.FileReader;
  3. import java.util.regex.Matcher;
  4. import java.util.regex.Pattern;
  5. public class IPRegexTestDemo {
  6.                     public static void main(String[] args) throws Exception {
  7.                                        getIPs();               
  8.              }
  9.                     public static void getIPs() throws Exception{
  10.                                       BufferedReader bufr=new BufferedReader (new FileReader("d:\\Test.txt"));
  11.                                        String line=null;
  12.                                        String iPRegString="\\b(([01]?\\d?\\d|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d?\\d|2[0-4]\\d|25[0-5])\\b";
  13.                                        Pattern p=Pattern.compile(iPRegString);
  14.                                       while((line=bufr.readLine())!=null) {
  15.                                           Matcher m=p.matcher(line);
  16.                                                  while(m.find()){
  17.                                                                                                      System.out.println(m.group());
  18.                                                                   }
  19.                                          }
  20.                     }
  21. }

复制代码
运行结果:
  1. 64.233.162.85
  2. 64.233.162.84
  3. 64.233.179.143
  4. 80.64.175.109
  5. 64.233.178.122
  6. 210.153.73.113
  7. 64.233.161.96
  8. 173.194.204.166
  9. 192.168.1.1
  10. 10.141.137.8
复制代码
程序截图:


IP正则表达式测试Demo.zip (8.35 KB, 下载次数: 74)
回复 使用道具 举报
major2015 发表于 2015-5-3 10:44
你要先想想怎么分别210.245.14.256和210.245.14.25
也就是,怎么判断是用三位数还是用二位数匹配,
貌似正 ...

有答案要通知我啊?虽然我不懂
回复 使用道具 举报
咪咪大人 发表于 2015-5-2 15:33
标准答案如下(第一题第二题加分题同时完成):

不厚道,自己一个人玩,给我啊,下次我提问再还给你就ok了

点评

- -你没说嘛 再说你也够25技术分惹- - 以及为了编辑答案方便- -  发表于 2015-5-3 20:08
回复 使用道具 举报
  1. \b(([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5])\b
复制代码

楼主不知这个正则有什么Bug?

点评

例如这个IP:064.233.162.85,会被当做结果匹配,而这不是一个标准的IP地址。  发表于 2015-5-3 20:59
回复 使用道具 举报
哦哦,多谢楼主,受教了!这个的确是疏忽了,:handshake
回复 使用道具 举报
哦  。。。。。。。。。。。。。。。。
回复 使用道具 举报
太长了,都不愿意看
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马