Claudius Ceteras wrote:

Besteht das Problem noch, oder hast Du es schon gelöst?

Ich habs mittlerweile gelöst, aber noch nicht 100% durchgetestet; habs mal angehängt. Ein Stack brauchts gar nicht, weil ich das HTML nicht validieren/parsen muss.

Gruss
Florian

using System;
using System.Text;
using System.Text.RegularExpressions;

namespace net.kruesch.WebUI.Util
{
    public static class HtmlUtil
    {
        public static string CutHtmlText(string htmlText, int maxIndex)
        {
            return CutHtmlText(htmlText, maxIndex, "");
        }

        public static string CutHtmlText(string htmlText, int maxIndex, String 
endFragment)
        {
                        // effektive Textlänge
            int effLen = maxIndex - endFragment.Length;
            if (effLen < 1) return endFragment;
                        
                        // entferne unnötige Leerzeichen
            htmlText = htmlText.Replace(System.Environment.NewLine, " ");
            htmlText = htmlText.Replace("  ", " ");
            htmlText = htmlText.Replace("&nbsp; ", " ");
            htmlText = htmlText.Replace(" &nbsp;", " ");

            string plainText = Regex.Replace(htmlText, @"<[^>]*>", ""); // 
strip HTML
            plainText = Regex.Replace(plainText, @"&(.)*;", " "); // strip 
Entities
            
            // Text-Länge liegt unter geünschter Länge
            if (plainText.Length <= effLen) return htmlText;
            
            plainText = plainText.Substring(0, Math.Min(effLen, 
plainText.Length));

            // letztes Leerzeichen            
            int lastSpaceIndex = plainText.LastIndexOf(" ");
            int lastNbspIndex = plainText.LastIndexOf("&nbsp;");
            
            int endIndex = lastSpaceIndex > lastNbspIndex ? lastSpaceIndex + 1 
: lastNbspIndex + 6;
      
            char c, n;
            int plainTextIndex = 0;
            StringBuilder strB = new StringBuilder();

            bool isHtmlTag = false;
            bool isOpeningTag = false;
            bool isClosedTag = false;
            bool isRelevantText = true;
            bool ignoreTag = false;
            bool isEntity = false;
            
            int openTagCount = 0; // Anzahl geöffneter Tags
            int ignoreTagCount = 0; // Anzahl geöffneter Tags, die ignoriert 
werden können

            // durchlaufe Text Zeichen für Zeichen
            for (int i = 0; i < htmlText.Length; i++)
            {
                c = htmlText[i]; // current char
                n = htmlText[i < (htmlText.Length - 1) ? i + 1 : i]; // next 
char            

                // Text-Ende noch nicht erreicht?
                isRelevantText = (plainTextIndex < endIndex);

                // Beginn eines HTML-Tag 
                if (c == '<')
                {
                    isHtmlTag = true;

                    // Tag wird geöffnet
                    isOpeningTag = (n != '/');

                    // Tag ist geschlossen
                    isClosedTag = (htmlText.IndexOf('>', i)) == 
(htmlText.IndexOf('/', i)) + 1;
                   
                    if (isRelevantText)
                    {
                        if (!isClosedTag)
                        {
                            openTagCount += isOpeningTag ? 1 : -1;
                        }
                      
                        ignoreTag = false;
                    }
                    else
                    {
                        if (isClosedTag)
                        {
                            ignoreTag = true;
                        }
                        else
                        {
                            if (isOpeningTag)
                            {
                                ignoreTagCount++;
                                ignoreTag = true;
                            }
                            else
                            {
                                // Closing tag
                                if (ignoreTagCount > 0)
                                {
                                    ignoreTagCount--;
                                    ignoreTag = true;
                                }
                                else
                                {
                                    openTagCount--;
                                    ignoreTag = false;
                                }
                            }
                        }
                    }
                }

                // Text
                if (!isHtmlTag)
                {
                    if (isRelevantText)
                    {
                        strB.Append(c);
                    }                   

                    // Entities als ein Zeichen zählen
                    if (isEntity && c==';') isEntity = false;
                    if (c == '&') isEntity = true;

                    if (!isEntity) plainTextIndex++;
                }
                else // HTML
                {
                    if (!ignoreTag) strB.Append(c);
                }

                if (c == '>')
                {
                    isHtmlTag = false;
                }
            }

            strB.Append(endFragment);

            return strB.ToString();
        }
    }
}

Antwort per Email an