【问题标题】:Word by word diff comparison of two strings in .NET.NET中两个字符串的逐字比较
【发布时间】:2009-11-23 22:03:28
【问题描述】:

我需要逐字比较两个字符串。 类似于 diff 之类的东西,但是对于文字,而不是对于行。

就像在维基百科中所做的那样 http://en.wikipedia.org/w/index.php?title=Horapollo&action=historysubmit&diff=21895647&oldid=21893459

结果我想返回两个单词的索引数组,它们在两个字符串中是不同的。

是否有任何适用于 .NET 的库/框架/独立方法可以做到这一点?

附:我想比较几千字节的文本

【问题讨论】:

标签: c# .net string string-comparison word-diff


【解决方案1】:

实际上,您可能想要实现我们在 DNA sequence alignments 中使用的局部对齐/全局对齐算法的变体。这是因为您可能无法对两个字符串进行逐字比较。即:

敏捷的棕色狐狸跳过 懒狗
敏捷的狐狸跳过 懒狗

换句话说,如果您无法识别整个单词的插入和删除,您的比较算法可能会变得非常严重。看看 Smith-Waterman 算法和 Needleman-Wunsch 算法,并找到一种方法让它们适应您的需求。由于如果字符串很长,这样的搜索空间会变得非常大,您还可以查看 BLAST。 BLAST 是一种非常常见的启发式算法,几乎是遗传搜索的标准。

【讨论】:

  • 我没明白,为什么我不能对两个字符串进行逐字比较?我想要的就像你说的 - 识别整个单词的插入和删除。
  • 因为如果你逐字比较,你的比较算法很快就会变得非常复杂。上面的例子很简单,但说明了这一点 我提出的序列算法旨在识别可比较序列中的间隙和插入。 PS:别忘了奖励你认为有帮助的答案。毕竟,这就是这个社区保持活力的方式。点击有用答案旁边的向上箭头图片。
【解决方案2】:

看来我找到了需要的解决方案:

DiffPlex 是 .NET 差异库与 Silverlight 和 HTML 差异查看器的组合。 http://diffplex.codeplex.com/

但它有一个错误。在“Hello-Kitty”“Hello - Kitty”这些行中,“Hello”这个词将被标记为差异。虽然区别是空格符号。

【讨论】:

    【解决方案3】:

    使用正则表达式。

    如示例:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Collections.Specialized;
    
    namespace WindowsApplication10
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                decimal discrimation = 0.75M;
                string formHeading = "The brown dog jumped over the red lazy river, and then took a little nap! Fun!";
                string userSearch = "The brown dog jumped over the red lazy river, and then took a little ";
                //string userSearch = "brown dog nap fun";
                decimal res = CompareText(formHeading, userSearch);
    
                if (res >= discrimation)
                {
                    MessageBox.Show("MATCH!" + res.ToString());
                }
                else 
                {
                    MessageBox.Show("does not match! " + res.ToString());
                }
            }
    
    
            /// <summary>
            /// Returns a percentage of 1 on how many words were matched
            /// </summary>
            /// <returns></returns>
            private decimal CompareText(string formHeading, string userSearch)
            {
                StringCollection formHeadingWords = new StringCollection();
                StringCollection userSearchWords = new StringCollection();
                formHeadingWords.AddRange(System.Text.RegularExpressions.Regex.Split(formHeading, @"\W"));
                userSearchWords.AddRange(System.Text.RegularExpressions.Regex.Split(userSearch, @"\W"));
    
                int wordsFound = 0;
                for (int i1 = 0; i1 < userSearchWords.Count; i1++)
                {
                    if (formHeadingWords.Contains(userSearchWords[i1]))
                        wordsFound += 1;
                }
                return (Convert.ToDecimal(wordsFound) / Convert.ToDecimal(formHeadingWords.Count));
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      你可以用唯一的数字替换你的 2 个文本中的所有单词,使用一些现成的代码来计算编辑距离,并将它的字符到字符的比较替换为数字到数字的比较,你就完成了!

      我不确定是否存在任何你想要的库。但是你肯定会发现很多编辑距离的代码。

      此外,根据您是否真的希望在编辑距离计算中允许替换,您可以更改动态编程代码中的条件。

      看到这个。 http://en.wikipedia.org/wiki/Levenshtein_distance

      【讨论】:

      • 其实我已经写了比较例程,但是我不喜欢它的工作方式,因为时不时会出现新的错误,但我没有太多时间去打,因为这是小程序所有功能的和平。这就是为什么我一直在寻找已经写好的经过测试的东西。它很有趣,但似乎这样的事情不存在:)
      • @Alex:见我上面的回答:)
      【解决方案5】:

      你可以试试这个,虽然我不确定你在找什么 StringUtils.difference() (http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#difference%28java.lang.String,%20java.lang.String%29)

      另外,Eclipse (eclipse.org) 项目有一个差异比较功能,这意味着他们还必须有代码来确定差异,您可以浏览他们的 API 或源代码以查看您可以找到的内容。

      祝你好运。

      【讨论】:

        【解决方案6】:
        【解决方案7】:

        还有一个用于 c# 的库是 diff-match-patch - http://code.google.com/p/google-diff-match-patch/

        它发现字符差异的坏处。好消息是,您必须添加说明以区分单词。

        【讨论】:

          猜你喜欢
          • 2012-08-02
          • 2019-01-14
          • 2015-06-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-10-29
          • 1970-01-01
          • 2012-11-07
          相关资源
          最近更新 更多