Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取HTML内容的前100个字符,而不剥离标记_C#_Asp.net_Html - Fatal编程技术网

C# 获取HTML内容的前100个字符,而不剥离标记

C# 获取HTML内容的前100个字符,而不剥离标记,c#,asp.net,html,C#,Asp.net,Html,关于如何剥离html标记有很多问题,但关于关闭它们的函数/方法的问题并不多。 情况是这样的。我有一个500个字符的消息摘要(包括html标记),但我只想要前100个字符。问题是如果我截断消息,它可能在HTML标签的中间…把事情搞砸了 假设html是这样的: “知识产权是一种权利,是一种精英,是劳动和财富的临时契约。 一些日期:2010年4月30日至5月2日 但是,在最低限度的情况下,我们必须遵守《劳动法》的规定,不因共同利益而放弃劳动。两人或两人的共同利益是不可分割的,因为他们的权利是不可分割的

关于如何剥离html标记有很多问题,但关于关闭它们的函数/方法的问题并不多。

情况是这样的。我有一个500个字符的消息摘要(包括html标记),但我只想要前100个字符。问题是如果我截断消息,它可能在HTML标签的中间…把事情搞砸了

假设html是这样的:

“知识产权是一种权利,是一种精英,是劳动和财富的临时契约。

一些日期:2010年4月30日至5月2日
但是,在最低限度的情况下,我们必须遵守《劳动法》的规定,不因共同利益而放弃劳动。两人或两人的共同利益是不可分割的,因为他们的权利是不可分割的。除了偶尔出于谨慎的考虑,不能因职权而受到惩罚。

有关Lorem Ipsum Doemdloye的更多信息,请访问:

我应该如何获取前100个左右的字符?(不过,理想情况下,应该是“内容”(在html标记之间)的前大约100个字符)

我假设实现这一点的最佳方法是一个递归算法,它跟踪html标记并附加任何被截断的标记,但这可能不是最好的方法


我的第一个想法是使用递归计算嵌套标记,当我们达到100个字符时,寻找下一个“如果将HTML解析为DOM结构,然后开始遍历广度优先或深度优先,收集节点文本,直到达到100个字符,会怎么样?

过去我用正则表达式完成了这项工作。抓取内容,通过正则表达式去掉标记,然后将其修剪到所需的长度


当然,它删除了所有的HTML,这就是我想要的。如果你想保留HTML,我会考虑不关闭打开的标签,而是删除打开的标签。

我的建议是找到一个HTML友好的遍历器(一个让你遍历HTML样的XML)。然后从最开始的标签开始忽略标签本身,只计算标签中的数据。将其计算到你的极限,然后一旦达到极限,就关闭每个标签(我想不出任何标签不仅仅是标签)

这应该是相当好的工作,并相当接近你所寻找的


这完全是老生常谈,所以我假设会有一些棘手的部分,比如显示的属性值(比如链接标签值)。

我决定推出自己的解决方案……只是为了迎接挑战

如果有人看到任何逻辑错误或效率低下,请告诉我

我不知道这是否是最好的方法…但它似乎有效。可能有些情况下它不起作用…如果html不正确,它可能会失败

/// <summary>
/// Get the first n characters of some html text
/// </summary>
private string truncateTo(string s, int howMany, string ellipsis) {

    // return entire string if it's more than n characters
    if (s.Length < howMany)
        return s;

    Stack<string> elements = new Stack<string>();
    StringBuilder sb = new StringBuilder();
    int trueCount = 0;

    for (int i = 0; i < s.Length; i++) {
        if (s[i] == '<') {

            StringBuilder elem = new StringBuilder();
            bool selfclosing = false;

            if (s[i + 1] == '/') {

                elements.Pop(); // Take the previous element off the stack
                while (s[i] != '>') {
                    i++;
                }
            }
            else { // not a closing tag so get the element name

                while (i < s.Length && s[i] != '>') {

                    if ((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z')) {
                        elem.Append(s[i]);
                    }
                    else if (s[i] == '/' || s[i] == ' ') {

                        // self closing tag or end of tag name. Find the end of tag
                        do {
                            if (s[i] == '/' && s[i + 1] == '>') {
                                // at the end of self-closing tag. Don't store
                                selfclosing = true;
                            }

                            i++;
                        } while (i < s.Length && s[i] != '>');
                    }
                    i++;
                } // end while( != '>' )

                if (!selfclosing)
                    elements.Push(elem.ToString());
            } 
        }
        else {
            trueCount++;
            if (trueCount > howMany) {
                sb.Append(s.Substring(0, i - 1));
                sb.Append(ellipsis);
                while (elements.Count > 0) {
                    sb.AppendFormat("</{0}>", elements.Pop());
                }
            }
        }
    }

    return sb.ToString();
}
//
///获取某些html文本的前n个字符
/// 
私有字符串truncateTo(字符串s,整数多少,字符串省略号){
//如果超过n个字符,则返回整个字符串
如果(s.长度<多少)
返回s;
堆栈元素=新堆栈();
StringBuilder sb=新的StringBuilder();
int-trueCount=0;
对于(int i=0;i='a'和&s[i]='a'和&s[i]');
}
i++;
}//结束时(!=“>”)
如果(!自动关闭)
elements.Push(elem.ToString());
} 
}
否则{
trueCount++;
如果(trueCount>多少){
sb.Append(s.Substring(0,i-1));
某人附加(省略号);
而(elements.Count>0){
sb.AppendFormat(“,elements.Pop());
}
}
}
}
使某人返回字符串();
}

我使用了XmlReader和XmlWriter来实现这一点:


正如其他人在这里提到的,您可能应该使用SgmlReader或HtmlAgilityPack来调整传入字符串的大小。

这是大多数情况下的解决方案。它不会处理不正确的html标记和类似“ac”的情况。但它适用于我的目的,可能会对其他人有所帮助

    /// <summary>
    /// Gets first number of characters from the html string without stripping tags
    /// </summary>
    /// <param name="htmlString">The html string, not encoded, pure html</param>
    /// <param name="length">The number of first characters to get</param>
    /// <returns>The html string</returns>
    public static string GetFirstCharacters(string htmlString, int length)
    {
        if (htmlString == null)
            return string.Empty;

        if(htmlString.Length < length)
            return htmlString;

        // regex to separate string on parts: tags, texts
        var separateRegex = new Regex("([^>][^<>]*[^<])|[\\S]{1}");
        // regex to identify tags
        var tagsRegex = new Regex("^<[^>]+>$");

        // separate string on tags and texts
        var matches = separateRegex.Matches(htmlString);

        // looping by mathes
        // if it's a tag then just append it to resuls,
        // if it's a text then append substing of it (considering the number of characters)
        var counter = 0;
        var sb = new StringBuilder();
        for (var i = 0; i < matches.Count; i++)
        {
            var m = matches[i].Value;

            // check if it's a tag
            if (tagsRegex.IsMatch(m))
            {
                sb.Append(m);
            }
            else
            {
                var lengthToCut = length - counter;

                var sub = lengthToCut >= m.Length
                    ? m
                    : m.Substring(0, lengthToCut);

                counter += sub.Length;
                sb.Append(sub);
            }
        }

        return sb.ToString();
    }
//
///从html字符串中获取第一个字符数,而不剥离标记
/// 
///html字符串,未编码,纯html
///要获取的第一个字符数
///html字符串
公共静态字符串GetFirstCharacters(字符串htmlString,整数长度)
{
if(htmlString==null)
返回字符串。空;
if(htmlString.Length][^]*[^$”;
//标记和文本上的分隔字符串
var matches=separateRegex.matches(htmlString);
//mathes循环
//如果它是一个标记,那么只需将其附加到results中,
//如果是文本,则附加其子字符串(考虑字符数)
var计数器=0;
var sb=新的StringBuilder();
for(var i=0;i=米长度
M
:m.子字符串(0,长度tocut);
计数器+=子长度;
某人追加(分);
}
}
使某人返回字符串();
}
<
 } while (i < s.Length && s[i] != '>');
 } while (i < s.Length && ***s[i+1]*** != '>');