用户在表单中以HTML格式输入文本,例如:
<p>this is my <strong>blog</strong> post,
very <i>long</i> and written in <b>HTML</b></p>
我希望能够只输出一部分字符串(例如20个第一个字符),而不会破坏用户输入的HTML结构。在这种情况下:
<p>this is my <strong>blog</strong> post, very <i>l</i>...</p>
呈现为
这是我的博客帖子,非常 lo ...
是否有能够执行此操作的Java库或使用简单方法?
MyLibrary.abbreviateHTML(string,20) ?
答案 0 :(得分:6)
由于正确地执行此操作并不容易,因此我通常会删除所有标记并截断。这样可以很好地控制文本大小和外观,通常需要将其放置在需要控制的位置。
请注意,您可能会发现我的提案非常保守,但实际上并不是您问题的正确答案。但大多数情况下,替代方案是:
截断HTML很困难的原因是您不知道截断会如何影响HTML的结构。你会如何在<ul>
中间截断,或者甚至最差,在复杂<table>
的中间截断?
因此,问题在于HTML不仅可以包含内容和样式(粗体,斜体),还可以包含结构(列表,表格,div等)。因此,一个好的和安全的实现方法是将所有内容分开内联的“样式”标签(粗体,斜体等)并截断,同时跟踪未关闭的标签。
答案 1 :(得分:3)
我不知道任何图书馆,但它不应该那么复杂(80%)。 您只需要一个简单的“解析器”来理解4种类型的令牌:
<
但不是</
开头且以>
结尾但不以/>
</
开头并以>
<br/>
) - 以<
但不是</
开头且以/>
结尾但不以>
然后你必须遍历输入字符串,并计算“普通字符”。当你沿着字符串行走并计数时,只要计算出的正常字符数小于或等于你想要的数量,就会将每个标记复制到输出中。
您还需要构建一堆当前打开的标记,同时您还要考虑输入。每次你走过一个“开始标记”,你把它放到堆栈(它的名字),每次你找到一个结束标记,你从堆栈中删除最顶层的标记名称(希望输入是正确的XHTML)。
当你到达所需数量的普通字符的末尾时,你只需要为堆栈中剩余的标签名称写下结束HTML标签。
但要小心,这只适用于输入结构良好的XML。
我不知道你想用这段代码做什么,但你应该注意HTML / JavaScript注入攻击。
答案 2 :(得分:1)
如果你真的想缩写HTML,那么就这样做(以所需长度剪切文本),将缩写结果通过http://jtidy.sourceforge.net/并希望最好。
答案 3 :(得分:0)
接下来有很多用于此常见任务的库和工具:
truncateNicely
的org.displaytag.util.HtmlTagUtil#abbreviateHtmlString
的