+ -
当前位置:首页 → 问答吧 → 多行匹配,并且只要最后一个匹配

多行匹配,并且只要最后一个匹配

时间:2010-08-31

来源:互联网

有如下的文件内容:

aaaaaa BBBBBBBBB cccccccccc
text1
text2
text3
dddd BBBBBBBBB eeeeeeeeeeeeeee
text4
text5
fffffffff BBBBBBBBB ggggg
text6
text7
text8
text9
mmm YYYYYYYYYYYYYY nnn
text10
text11
ZZZZZZZZZZZZZZZ
text12
text13
END



要求先找到YYYYYYYYYYYYYY,并只输出前后“BBBBBBBBB”和“ZZZZZZZZZZZZZZZ”之间的内容。期望输入如下:
fffffffff BBBBBBBBB ggggg
text6
text7
text8
text9
mmm YYYYYYYYYYYYYY nnn
text10
text11
ZZZZZZZZZZZZZZZ


注意,文件中有很多行都包含“BBBBBBBBB”,我只需要最后那一个“BBBBBBBBB”开始,直到“ZZZZZZZZZZZZZZZ”结束之间的内容。

作者: linlone   发布时间: 2010-08-31

本帖最后由 zhasm 于 2010-09-01 09:30 编辑

两种方法,一种是依靠编程,按楼主给出的思路实现,另一种靠正则。

1.将文本按行存入数组;找到YYY所在的行,记下行号,回退到BBB所在的行,然后顺序开始打印,一直到ZZZ行。
  1. #!/usr/bin/perl
  2. $txt=<<END;
  3. aaaaaa BBBBBBBBB cccccccccc
  4. text1
  5. text2
  6. text3
  7. dddd BBBBBBBBB eeeeeeeeeeeeeee
  8. text4
  9. text5
  10. fffffffff BBBBBBBBB ggggg
  11. text6
  12. text7
  13. text8
  14. text9
  15. mmm YYYYYYYYYYYYYY nnn
  16. text10
  17. text11
  18. ZZZZZZZZZZZZZZZ
  19. text12
  20. text13
  21. END

  22. @lines=split (/\s*\n\s*/g,$txt);
  23. $max=@lines;
  24. $i=0;

  25. while ($i < $max)
  26. {
  27.     last if $lines[$i]=~ /\bYYYYYYYYYYYYYY\b/;
  28.     $i++;
  29. }
  30. while($i>0)
  31. {
  32.     last if $lines[$i]=~/\bBBBBBBBBB\b/;
  33.     $i--;
  34. }
  35. while($i<$max)
  36. {
  37.     print $lines[$i],"\n";
  38.     last if $lines[$i]=~/\bZZZZZZZZZZZZZZZ\b/;
  39.     $i++;
  40. }
复制代码
输出结果为:
  1. fffffffff BBBBBBBBB ggggg
  2. text6
  3. text7
  4. text8
  5. text9
  6. mmm YYYYYYYYYYYYYY nnn
  7. text10
  8. text11
  9. ZZZZZZZZZZZZZZZ
复制代码
2. 正则。找到BBB行,它之后应该若干个(不匹配BBB,YYY,ZZZ)的行,或者是匹配(YYY)的行, 然后以zzz行结束。

仍沿用上例中对$txt的定义,代码如下:
  1. if ($txt=~
  2.         m/
  3.     (
  4.         ^\w+\s+BBBBBBBBB\s+\w+\s*$ \n
  5.         (?:
  6.             ^(?:
  7.                 (?!\b(?:BBBBBBBBB|YYYYYYYYYYYYYY|ZZZZZZZZZZZZZZZ)\b).)+$ \n
  8.                 |
  9.                 ^\w+\s+YYYYYYYYYYYYYY\s+\w+\s*$ \n
  10.             )+
  11.         ^ZZZZZZZZZZZZZZZ$
  12.     )
  13.     /mx )
  14.         {
  15.         print $1;
  16.     }
复制代码
输出结果与上同。

作者: zhasm   发布时间: 2010-09-01