84366992 发表于 2018-8-31 08:37:44

perl 正则匹配嵌套结构

  有这么一道题。。
  


[*]aaa
[*]bbb
[*]#if defined(__MMI_DEL__)
[*]   ccc
[*]#endif
[*]ddd
[*]eee
[*]#if defined(__MMI_DEL__)
[*]   fff
[*]   ggg
[*]#endif
[*]hhh
  

要求匹配
注释外的内容,匹配之后的内容:
aaa
bbb
ddd
eee
hhh
可以利用/^xxx/../^xxx/结构来匹配 ,但是出现了以下的嵌套结构,  


[*]aaa
[*]bbb
[*]#if defined(__MMI_DEL__)
[*]   ccc
[*]#endif
[*]ddd
[*]eee
[*]#if defined(__MMI_DEL__)
[*]   fff
[*]   ggg
[*]#if defined(__EX222__)
[*]   KKK
[*]#if defined(__EX222__)
[*]woshi
[*]#endif
[*]LLLL
[*]#endif
[*]#endif
[*]sdffff
[*]#if defined(__EX222__)
[*]sdfsdf
[*]sdff
[*]#endif
[*]sdfdsf
  

就没法用用上面的结构了,必须要使用平衡组,或者是递归来做,其实上面的代码也可以看做是
这种类型,简单点就是(1*(1+2)/3)这种类型的括号嵌套,可以利用(?R)来递归(perlre中有详解),或者是(??{code})
动态正则表达式结构。
以下我利用(??{code})来示范写了一段。。  


[*]#!/usr/bin/perl
[*]use strict;
[*]use warnings;
[*]my (@arr,$re,$line,@tmp);
[*]while(){
[*]chomp;
[*]   s/#if\s*defined.*?$/(/g;#这里替换成(和)方便匹配
[*]   s/#endif/)/g;
[*]   push @arr,$_;
[*]}
[*]$line .= "$_\_" for @arr;
[*]#print $line;
[*]$re = qr/(?>[^()]+|\((??{$re})\))*/;
[*]while($line =~ /(\w*)\($re\)(\w+)/g){
[*]    push @tmp,split/\_/,"$1$2";
[*]}
[*]print join("\n",@tmp);
[*]__DATA__
[*]aaa
[*]bbb
[*]#if defined(__MMI_DEL__)
[*]   ccc
[*]#endif
[*]ddd
[*]eee
[*]#if defined(__MMI_DEL__)
[*]   fff
[*]   ggg
[*]#if defined(__EX222__)
[*]   KKK
[*]#if defined(__EX222__)
[*]woshi
[*]#endif
[*]LLLL
[*]#endif
[*]#endif
[*]sdffff
[*]#if defined(__EX222__)
[*]sdfsdf
[*]sdff
[*]#endif
[*]sdfdsf
  

  output:

aaa
bbb  


ddd
eee  


sdffff  


sdfdsf

页: [1]
查看完整版本: perl 正则匹配嵌套结构