免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 7942 | 回复: 22
打印 上一主题 下一主题

嵌套括号的递归匹配中,look-around assertions不生效 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-08-21 18:14 |只看该作者 |倒序浏览
本帖最后由 routesf 于 2013-08-23 11:54 编辑

如下程序,括号{}的递归匹配被DATA中的引号中的一个}干扰,导致最终输出的结果少一个},我试图用(?<!\\)来屏蔽 “dfa-pattern "(ST\x00 01\xC|\x00\xX\x08 00\x\}\x08 0d 0a\x).*";”中的那个导致问题的\},但是不成功,有没有谁用过类似的东西

一个方案是用Text::Balanced,它可以忽略文中处于引号中的{},但是对格式要求比较严格,不如正则灵活,我想用正则来解决这个问题,但是一直没找到可行的方法
  1. #!/usr/bin/perl5.12 -w

  2. use strict;

  3. my $ptn_no_keyword = qr/(
  4.            ([\S]+)\s
  5.                         (
  6.                                 \{
  7.                                         (
  8.                                                 (?:
  9.                                                         (?>[^{}]+)
  10.                                                         |
  11.                                                         (?3)
  12.                                                  )*
  13.                                         )
  14.                                 \}
  15.                         )
  16.         )/x;
  17. local $/;
  18. my $cfg = <DATA>;
  19. if ($cfg =~ /$ptn_no_keyword/) {
  20.                 print "$1\n";
  21. } else {
  22.                 print "Not matched\n";
  23. }
  24. __DATA__
  25. application junos:PCANYWHERE {
  26.         type PCANYWHERE;
  27.         index 121;
  28.         port-mapping {
  29.                 port-range {
  30.                         tcp 5631;
  31.                         udp 5632;
  32.                 }
  33.         }
  34.         signature {
  35.                 port-range {
  36.                         tcp 0-65535;
  37.                         udp 0-65535;
  38.                 }
  39.                 client-to-server {
  40.                         dfa-pattern "(ST|\x00 00 00 00\x).*";
  41.                 }
  42.                 server-to-client {
  43.                         dfa-pattern "(ST\x00 01\xC|\x00\xX\x08 00\x\}\x08 0d 0a\x).*";
  44.                 }
  45.                 min-data 8;
  46.                 order 85;
  47.         }
  48. }
复制代码

论坛徽章:
3
CU十二周年纪念徽章
日期:2013-10-24 15:41:34子鼠
日期:2013-12-14 14:57:19射手座
日期:2014-04-25 21:23:23
2 [报告]
发表于 2013-08-22 16:08 |只看该作者
{:3_186:} 写的有点蛋疼 ,效果实现了,我在引号中多加了几个\{\}回复 1# routesf
  1. #!/usr/bin/perl5.12 -w
  2. use strict;
  3. local $/;
  4. my $cfg = <DATA>;
  5. my @m   = $cfg =~ /"[^"]+"/g;    #取引号中的字符串
  6. my $count;
  7. for (@m) {
  8.     1 while (/\\}(?{$count++})/g);
  9.     1 while (/\\{(?{$count--})/g);    #计算引号中的\{ 或\}个数
  10. }
  11. my $ptn_no_keyword = qr/((?{local $a=$count})(?>(?:([^{}]+)|  
  12.                         {(?{$a++})|      #遇到开括号$a+1
  13.                         }(?(?{$a!=0})(?{$a--})|  #如果$a不等于0则遇到闭括号$a-1
  14.                         (?!)))*)(?(?{$a!=0})(?!)))/x
  15.   ;    # 否则继续匹配,如果继续遇到$a不等于0 继续匹配到行尾
  16. if ( $cfg =~ /$ptn_no_keyword/ ) {
  17.     print "$1\n";
  18. }
  19. else {
  20.     print "Not matched\n";
  21. }
  22. __DATA__
  23. application junos:PCANYWHERE {
  24.         type PCANYWHERE;
  25.         index 121;
  26.         port-mapping {
  27.                 port-range {
  28.                         tcp 5631;
  29.                         udp 5632;
  30.                 }
  31.         }
  32.         signature {
  33.                 port-range {
  34.                         tcp 0-65535;
  35.                         udp 0-65535;
  36.                 }
  37.                 client-to-server {
  38.                         dfa-pattern "(ST|\x00 00 \}00 00\x).*";
  39.                 }
  40.                 server-to-client {
  41.                         dfa-pattern "(ST\x00 01\xC|\x00\xX\x08\} \{00\x\}\x08 0d 0a\x).*";
  42.                 }
  43.                 min-data 8;
  44.                 order 85;
  45.         }
  46. }
复制代码

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
3 [报告]
发表于 2013-08-22 16:43 |只看该作者
回复 1# routesf
  1. my $ptn_no_keyword = qr/(
  2.            ([\S]+)\s
  3.                         (
  4.                                 \{
  5.                                         (
  6.                                                 (?:
  7.                                                         (?>[^{}]+)
  8.                                                         |
  9.                                                         (?3)
  10.                                                         |
  11.                                                         (?>(\}|\{))   # adding another case
  12.                                                  )*
  13.                                         )
  14.                                 \}
  15.                         )
  16.         )/x;
复制代码

论坛徽章:
0
4 [报告]
发表于 2013-08-23 11:51 |只看该作者
感谢回复,我试了一下这个ptn,发现数据小的时候没问题,如果数据量比较大,则会出现out of memory,可见又加一个alternation对效率的影响非常大,附件是我用的文件,我的机器是CentOS4.5, 1G mem

回复 3# yinyuemi


   

论坛徽章:
0
5 [报告]
发表于 2013-08-23 11:55 |只看该作者
传不了附件啊
回复 4# routesf


   

论坛徽章:
0
6 [报告]
发表于 2013-08-23 11:59 |只看该作者
mcshell对regex的了解相当纯熟啊,先感谢,回头好好研究学习一下你的code

回复 2# mcshell


   

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
7 [报告]
发表于 2013-08-23 12:06 |只看该作者
回复 4# routesf


    数据量大的话,一般不推荐re,尤其当使用了回溯,用打点法比较保险和高效

论坛徽章:
0
8 [报告]
发表于 2013-08-23 13:14 |只看该作者
像mcshell这种算是打点法吗

回复 7# yinyuemi


   

求职 : 软件工程师
论坛徽章:
3
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2016-05-05 06:20:00
9 [报告]
发表于 2013-08-23 14:51 |只看该作者
看不懂需求,通常这种情况,可以先将捣乱的符号用另外一个符号替换掉,然后在做处理。处理完后,在恢复。

论坛徽章:
3
CU十二周年纪念徽章
日期:2013-10-24 15:41:34子鼠
日期:2013-12-14 14:57:19射手座
日期:2014-04-25 21:23:23
10 [报告]
发表于 2013-08-23 15:29 |只看该作者
回复 8# routesf


    和堆栈的算法差不多。。。不过我也不懂什么算法
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP