duanhongxian6982 2016-07-04 12:25
浏览 44
已采纳

使用正则表达式提取文本块

Using PHP I want to compare two text files, the first file is the main one that the other one should compare with it. If a line of first.txt does not exist in second.txt or is different from it, the script should return the whole block of that line, for example:

first.txt

interface Vlan11
 description xxx
 ip address 10.10.10.10 255.255.255.255
 shutdown
!
vlan 34
!
vlan 17
 name sth
!
route-map sth
 match ip address exm
 set ip next-hop 1.2.3.4
!

second.txt

interface Vlan11
 description xxx
 ip address 20.20.20.20 255.255.255.255
 shutdown
!
vlan 34
!
route-map sth
 match ip address exm
 set ip next-hop 1.2.3.4
!

For the compare I extracted the first.txt lines using file() and search them in the second.txt, now the IP address is different in third line of second.txt, then we should return the block of this line (from interface to the bang(!)):

interface Vlan11
 description xxx
 ip address 20.20.20.20 255.255.255.255
 shutdown
!

or in the second.txt one of vlan blocks does not exists, so it should returns:

vlan 17
 name sth
!

It's easy to write a regex that extracts the block between the two bangs, but because I should go back to the start of block I don't know what the pattern should start with.

Also I have another idea that every block starts with a character, then some lines that start with a space and then a bang at the end, but the problem is about how to start the pattern.

  • 写回答

2条回答 默认 最新

  • douwei7471 2016-07-04 21:37
    关注

    You could use the following regular expression to match blocks:

    /.*?\R!\R*/s
    

    The \R matches newlines, and the s modifier makes sure that . will also match newlines.

    You could then use preg_match_all to get all blocks from a text, and use array_diff to make the comparison and extract the blocks that are different:

    $text1 = file_get_contents("first.txt");
    $text2 = file_get_contents("second.txt");
    
    preg_match_all('/.*?\R!\R*/s', $text1, $blocks1);
    preg_match_all('/.*?\R!\R*/s', $text2, $blocks2);
    
    $result = array_diff($blocks1[0], $blocks2[0]);
    
    print_r($result);
    

    See it run on eval.in;

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog