Strings vergleichen und Unterschiede visuell darstellen

Ich musste für ein ASP.NET-Projekt die Unterschiede von zwei Texten visuell darstellen, ähnlich wie bekannte Diff-Tools (Araxis Merge, WinDiff etc.) dies tun.

Bloß wie vorgehen? Ich habe mich dazu entschlossen, die Strings jeweils Wortweise in ein Array zu splitten und dann die Inhalte der Arrays zu vergleichen. Wenn ein Wort nicht passt, dann wird dieses mit einem HTML-Tag <b>match</b> versehen und nachdem die Arrays durchlaufen sind, wird die geänderte Zeichenfolge zurückgeliefert.

Der Ablauf im einzelnen:

  • Strings einlesen
  • in ein String-Array einlesen
  • Da die Arrays unterschiedlich dimensioniert sein können, ein Rezise durchführen
  • Helfer-Methode aufrufen um NULL-Werte innerhalb eines Arrays zu verhindern und mit Leer-Strings ersetzen
  • Schleife durchlaufen und Unterscheidungen mit <b>Wort</b> versehen.
  • String zurückgeben

/// <summary>

/// Compares two strings and return a new string with

/// HTML-Tags that marks the changes.

/// </summary>

/// <param name=“strTextOld“>Originalstring</param>

/// <param name=“strTextNew“>Geänderter String</param>

/// <returns>String</returns>

public static string CompareWithHtml(string strTextOld, string strTextNew)

{

    return (CompareWithHtml(strTextOld, strTextNew, false));

}

 

/// <summary>

/// Compares two strings and return a new string

/// with HTML-Tags that marks the changes.

/// </summary>

/// <param name=“strTextOld“>Originalstring</param>

/// <param name=“strTextNew“>Geänderter String</param>

/// <param name=“ignoreHTML“>Wenn <c>true</c> werden HTML-Tags ignoriert.</param>

/// <returns>String</returns>

public static string CompareWithHtml(string strTextOld, string strTextNew, bool ignoreHTML)

{

    if (string.IsNullOrEmpty(strTextOld))

    {

        throw new ArgumentNullException(„strTextOld“,

                 
string
.Format(

                               
„Parameter darf nicht leer sein! Parametername {0}“,

                                strTextOld));

    }

    if (string.IsNullOrEmpty(strTextNew))

    {

        throw new ArgumentNullException(„strTextNew“,

                   string.Format(

                               
„Parameter darf nicht leer sein! Parametername {0}“,

                               
strTextNew));

    }

 

    if(ignoreHTML)

    {

        strTextNew = EleminateHtml(strTextNew);

    }

 

    string[] arWordsAlt = strTextOld.Split(new Char[] { ‚ ‚ });

    string[] arWordsNeu = strTextNew.Split(new Char[] { ‚ ‚ });

 

    int iLen1 = arWordsAlt.Length;

    int iLen2 = arWordsNeu.Length;

 

    if (iLen1 > iLen2)

    {

        Array.Resize(ref arWordsNeu, iLen1);

        arWordsNeu = ChkNullValues(arWordsNeu);

    }

    else if (iLen1 < iLen2)

    {

        Array.Resize(ref arWordsAlt, iLen2);

        arWordsAlt = ChkNullValues(arWordsAlt);

    }

 

    string strNewVal = string.Empty;

 

    for (int i = 0; i < arWordsAlt.Length; i++)

    {

        if (!arWordsAlt[i].Equals(arWordsNeu[i], StringComparison.Ordinal))

        {

            strNewVal += „<b>“ + arWordsNeu[i] + „</b>“ + ‚ ‚;

 

        }

        else

        {

            strNewVal += arWordsAlt[i] + ‚ ‚;

        }

    }

    return (strNewVal);

}

 

/// <summary>

/// Prüft, ob im Array Null-Werte vorhanden sind.

/// Wenn ja, dann mit Leer-String auffüllen

/// </summary>

/// <param name=“pArray“>Das Array mit den Inhaltswerten.</param>

/// <returns></returns>

private static string[] ChkNullValues(string[] pArray)

{

    if(pArray.Length > 0)

    {

        for(int i = 0; i < pArray.Length;i++)

        {

            if(string.IsNullOrEmpty(pArray[i]))

            {

                pArray.SetValue(string.Empty, i);

            }

        }

    }

    return pArray;           

 

private static string EleminateHtml(string pString)

{

    string newString = string.Empty;

    //Tags entfernen

    Regex textreplace = new Regex(„(<[^>]*>)“);

    newString = textreplace.Replace(pString, „“);

    return newString;

}

Das Demo-Projekt kannst Du dir hier herunterladen: [Download]