decatur-vote/text-diff

一个生成易于人类阅读的纯文本格式差异的最小库。差异允许将旧文本转换为新文本,反之亦然。

1.0.0 2023-05-16 17:07 UTC

This package is auto-updated.

Last update: 2024-09-30 01:38:09 UTC


README

PHP 文本差异

一个生成易于人类阅读的纯文本格式差异的最小库。差异允许将旧文本转换为新文本,反之亦然。

安装

composer require decatur-vote/text-diff v1.0.x-dev   

或在你的 composer.json

{"require":{ "decatur-vote/text-diff": "v1.0.x-dev"}}  

使用

生成差异,并使用操作(opps)向前或向后移动。

<?php  
  
$differ = new \DecaturVote\Differ();  
$old = 'old text';  
// $old = $differ->fix_html($old); # optional - will beautify html using DOMDocument, via composer package taeluf/phtml   
$new = 'new text';  
$opps = $differ->get_opps($old, $new);  
// file_put_contents('file_path.txt', $opps)  
  
$recovered_old_text = $differ->backward($new, $opps);  
$restored_new_text = $differ->forward($old, $opps);  

注意

  • 生成两个15,000字符字符串的差异需要122ms(在我的机器上),然后运行两个 forward()backward()。通过 phptest LargeRandomStringDiffs 运行。
  • phptest -test MultipleDiffs -run dup - 测试特定的差异测试。请参阅测试类。
  • 有27个不同的差异测试都通过了,其中一些是在通过 LargeRandomStringDiffs 测试发现错误时添加的。大多数(可能全部)错误都是由于重复行没有被处理。

待办事项?

  • 创建差异HTML(我不知道我的 move 操作如何与它一起工作,所以可能不会这样做)

工作原理

Differ 的工作概述。我们将介绍差异看起来像什么,如何处理它们,然后是它们是如何创建的。

差异看起来像什么

这将删除第1行和第3行,在第3行和第5行添加行 'c' 和 'def',然后将第6行移动到第4行,第7行移动到第3行。

1-abc  
3-baby  
3+c  
5+def  
6>4  
7>3  

注意:基于0的行索引。第一行是第 0 行。第二行是第 1 行。1-abc 意味着在 abc 之前有一行。

注意:删除和添加行操作依赖于先前指令已经应用。上面的 3-baby 表示 '删除包含文本 "baby" 的第3行'。然而,原始文本中 baby 是第4行。3-baby1-abc 之后处理,因此删除第1行后,第4行("baby")成为第3行,所以我们得到 3-baby

处理差异

向前差异按从上到下的顺序处理,始终按此顺序

  1. 删除行
  2. 添加行
  3. 移动行

注意:对于 6>4,第4行被第6行替换。第6行保持不变,除非其他移动操作覆盖了第6行。

向后差异从下往上处理

  1. 移动行
  2. 删除作为 add 操作列出的行(例如,5+def 将被删除)
  3. 添加作为 remove 操作列出的行(例如,1-abc 将被添加)

生成差异

在各个阶段处理重复行(算法的大部分复杂性来自于管理重复行)。

  1. $old_text$new_text 生成行数组
  2. $old_text 中找到不存在于 $new_text 中的任何行,并为这些行生成删除操作
  3. $new_text 中找到不存在于 $old_text 中的任何行,并为这些行生成添加操作
  4. 将删除和添加操作应用于 $old_text,以创建新文本的无序副本。
  5. 将无序新文本的每一行与提供的 $new_text 进行比较。找到正确的位置。