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 Jenkins+k8s部署slave节点offline
  • ¥15 微信小游戏反编译后,出现找不到分包的情况
  • ¥15 如何实现从tello无人机上获取实时传输的视频流,然后将获取的视频通过yolov5进行检测
  • ¥15 WPF使用Canvas绘制矢量图问题
  • ¥15 用三极管设计一个单管共射放大电路
  • ¥15 孟德尔随机化r语言运行问题
  • ¥15 pyinstaller编译的时候出现No module named 'imp'
  • ¥15 nirs_kit中打码怎么看(打码文件是csv格式)
  • ¥15 怎么把多于硬盘空间放到根目录下
  • ¥15 Matlab问题解答有两个问题