如何使用C#展示单词差异?

19
我想展示两个文本块之间的差异。与其比较文本行或单个字符,我想仅比较由指定字符(例如'\n'' ''\t')分隔的单词。我的主要原因是,我将要比较的文本块通常没有很多换行符,并且字母比较可能难以理解。
我遇到了以下用于比较行和字符的O(ND)逻辑C#代码,但我不知道如何修改它来比较单词。
此外,我想跟踪单词之间的分隔符并确保它们包含在差异中。因此,如果空格被硬回车替换,我希望这会显示为差异。
我使用Asp.net来显示整个文本块,包括已删除的原始文本和已添加的新文本(两者都将突出显示以表明它们已被删除/添加)。希望您能提供适用于这些技术的解决方案。
感谢任何有关如何完成此操作的建议!

玩得开心。我的一位同事有机会为我们的旗舰产品系列发布做这件事。他受到了足够的挑战。他使用了几篇理论论文来指导他的工作...整个过程中都在抱怨写作质量。 - Jason D
4个回答

19

微软在 CodePlex 上发布了一个 diff 项目,可以让你进行单词、字符和行的比较。该项目采用 Microsoft Public License (Ms-PL) 许可证。

https://github.com/mmanela/diffplex


2
DiffPlex允许您定义一个自定义函数来分割文本,以便进行差异比较。您可以使用以下方法: DiffResult CreateCustomDiffs(string oldText, string newText, bool ignoreWhiteSpace, Func<string, string[]> chunker)其中chunker告诉DiffPlex哪些是要相互比较的原子单元。 - Matthew Manela
嗨,Jim,我正在寻找类似的解决方案,想知道您是否认为使用diffplex能够解决您的问题? - CHash11
看起来我在我的解决方案中使用了http://www.codeproject.com/Articles/11454/A-word-wise-HTML-text-compare-and-merge-engine。我不记得为什么我选择了它而不是diffplex,说实话。这种解决方案用定义的HTML标签包装删除和添加的单词,使您可以根据需要进行样式设置。 - Jim Geurts

1

除了一些通用的优化之外,如果您需要在比较中包含分隔符,则基本上是进行带有断点的逐字符比较。虽然您可以使用您提供的O(ND),但您将对其进行的更改与编写自己的代码相同。

差异比较的主要问题是找到连续性(如果我删除一个单词,但保留其余部分不变)。

如果您想使用他们的代码,请从示例开始,不要编写已删除的字符,如果在相同位置替换了字符,则不要输出此结果。然后,您需要计算“更改”单词的最长连续运行,突出显示此字符串并输出。

很抱歉这不是很好的答案,但对于这个问题,答案基本上是编写和调整函数。


0

字符串 string1 = "你好世界,你怎么样"; 字符串 string2 = "你好,你怎么样";

        var first = string1.Split(' ');
        var second = string2.Split(' ');
        var primary = first.Length > second.Length ? first : second;
        var secondary = primary == second ? first : second;
        var difference = primary.Except(secondary).ToArray();

0

使用 String.Split 函数,以 '\n'、' ' 和 '\t' 作为分隔符,将返回文本块中的单词数组。

然后,您可以比较每个数组以查找差异。简单的一对一比较将告诉您是否更改了任何单词。比较:

hello world how are you

并且:

hello there how are you

会给你那个world并改为there

但它不会告诉你是否插入或删除了单词,你仍需要逐个字符解析文本块,以查看分隔符字符是否已更改。


1
我担心对于大块文本使用String.Split会效率低下。 - Vadym Stetsiak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接