decatur-vote / text-diff
一个生成易于人类阅读的纯文本格式差异的最小库。差异允许将旧文本转换为新文本,反之亦然。
1.0.0
2023-05-16 17:07 UTC
Requires (Dev)
- taeluf/code-scrawl: v0.8.x-dev
- taeluf/phtml: v0.1.x-dev
- taeluf/tester: v0.3.x-dev
Suggests
- taeluf/phtml: Used by TextDiff to beautify HTML, so that HTML is multi-line & can be diff'd.
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-baby
在 1-abc
之后处理,因此删除第1行后,第4行("baby")成为第3行,所以我们得到 3-baby
。
处理差异
向前差异按从上到下的顺序处理,始终按此顺序
- 删除行
- 添加行
- 移动行
注意:对于 6>4
,第4行被第6行替换。第6行保持不变,除非其他移动操作覆盖了第6行。
向后差异从下往上处理
- 移动行
- 删除作为
add
操作列出的行(例如,5+def
将被删除) - 添加作为
remove
操作列出的行(例如,1-abc
将被添加)
生成差异
在各个阶段处理重复行(算法的大部分复杂性来自于管理重复行)。
- 为
$old_text
和$new_text
生成行数组 - 在
$old_text
中找到不存在于$new_text
中的任何行,并为这些行生成删除操作 - 在
$new_text
中找到不存在于$old_text
中的任何行,并为这些行生成添加操作 - 将删除和添加操作应用于
$old_text
,以创建新文本的无序副本。 - 将无序新文本的每一行与提供的
$new_text
进行比较。找到正确的位置。