perl 正则匹配嵌套结构

有这么一道题。。

 
  
  1. aaa  
  2. bbb  
  3. #if defined(__MMI_DEL__)  
  4.    ccc  
  5. #endif  
  6. ddd  
  7. eee  
  8. #if defined(__MMI_DEL__)  
  9.    fff  
  10.    ggg  
  11. #endif  
  12. hhh 
要求匹配
注释外的内容,匹配之后的内容:
aaa
bbb
ddd
eee
hhh
可以利用/^xxx/../^xxx/结构来匹配 ,但是出现了以下的嵌套结构,

 

 
  
  1. aaa  
  2. bbb  
  3. #if defined(__MMI_DEL__)  
  4.    ccc  
  5. #endif  
  6. ddd  
  7. eee  
  8. #if defined(__MMI_DEL__)  
  9.    fff  
  10.    ggg  
  11. #if defined(__EX222__)  
  12.    KKK  
  13. #if defined(__EX222__)  
  14. woshi  
  15. #endif  
  16.   LLLL  
  17. #endif  
  18. #endif  
  19. sdffff  
  20. #if defined(__EX222__)  
  21. sdfsdf  
  22. sdff  
  23. #endif  
  24. sdfdsf 
就没法用用上面的结构了,必须要使用平衡组,或者是递归来做,其实上面的代码也可以看做是<div></div>
这种类型,简单点就是(1*(1+2)/3)这种类型的括号嵌套,可以利用(?R)来递归(perlre中有详解),或者是(??{code})
动态正则表达式结构。
以下我利用(??{code})来示范写了一段。。
 
 
  
  1. #!/usr/bin/perl  
  2. use strict;  
  3. use warnings;  
  4. my (@arr,$re,$line,@tmp);  
  5. while(<DATA>){  
  6. chomp;  
  7.    s/#if\s*defined.*?$/(/g;  #这里替换成(和)方便匹配  
  8.    s/#endif/)/g;  
  9.    push @arr,$_;  
  10. }  
  11. $line .= "$_\_" for @arr;  
  12. #print $line;  
  13. $re = qr/(?>[^()]+|\((??{$re})\))*/;  
  14. while($line =~ /(\w*)\($re\)(\w+)/g){  
  15.     push @tmp,split/\_/,"$1$2";  
  16. }  
  17. print join("\n",@tmp);  
  18. __DATA__  
  19. aaa  
  20. bbb  
  21. #if defined(__MMI_DEL__)  
  22.    ccc  
  23. #endif  
  24. ddd  
  25. eee  
  26. #if defined(__MMI_DEL__)  
  27.    fff  
  28.    ggg  
  29. #if defined(__EX222__)  
  30.    KKK  
  31. #if defined(__EX222__)  
  32. woshi  
  33. #endif  
  34.   LLLL  
  35. #endif  
  36. #endif  
  37. sdffff  
  38. #if defined(__EX222__)  
  39. sdfsdf  
  40. sdff  
  41. #endif  
  42. sdfdsf 

 output:

aaa
bbb

 
ddd
eee

 
sdffff

 
sdfdsf









本文转自 mcshell 51CTO博客,原文链接:http://blog.51cto.com/mcshell/1153951,如需转载请自行联系原作者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值