【问题标题】:Replacing newline characters with <br> inside a child element using Jsoup使用 Jsoup 在子元素中用 <br> 替换换行符
【发布时间】:2013-12-14 06:03:06
【问题描述】:

我在使用 Jsoup 替换给定 HTML 中所有 &lt;pre&gt; 元素中的换行符时遇到问题。 这是我到目前为止所尝试的,以及我面临的问题。 我正在尝试将所有\n 字符替换为仅在所有&lt;pre&gt; 标记中的innerHtml 的&lt;br&gt;。我想保留其余内容。 代码是:

String body = "<p>This is the output:</p>\n<pre class=\"lang-xml prettyprint prettyprinted\">\n<code><span class=\"dec\">&lt;!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"&gt;</span><span class=\"pln\">\n</span><span class=\"tag\">&lt;HTML&gt;</span><span class=\"pln\">\n    </span><span class=\"tag\">&lt;HEAD&gt;</span><span class=\"pln\">\n        </span><span class=\"tag\">&lt;META</span><span class=\"pln\"> </span><span class=\"atn\">http-equiv</span><span class=\"pun\">=</span><span class=\"atv\">\"Content-Type\"</span><span class=\"pln\"> </span><span class=\"atn\">content</span><span class=\"pun\">=</span><span class=\"atv\">\"text/html; charset=iso-8859-1\"</span><span class=\"tag\">&gt;</span><span class=\"pln\">\n        </span><span class=\"tag\">&lt;TITLE&gt;</span><span class=\"pln\">GeteBayOfficialTime</span><span class=\"tag\">&lt;/TITLE&gt;</span><span class=\"pln\">\n    </span><span class=\"tag\">&lt;/HEAD&gt;</span><span class=\"pln\">\n    </span><span class=\"tag\">&lt;BODY&gt;</span><span class=\"pln\">\n\n* About to connect() to api.ebay.com port 443 (#0)\n*   Trying 66.135.211.100... * Timeout\n*   Trying 66.135.211.140... * Timeout\n*   Trying 66.211.179.150... * Timeout\n*   Trying 66.211.179.180... * Timeout\n*   Trying 66.135.211.101... * Timeout\n*   Trying 66.211.179.148... * Timeout\n* connect() timed out!\n* Closing connection #0\n</span><span class=\"tag\">&lt;P&gt;</span><span class=\"pln\">Error sending request</span></code></pre>";
            log.info("printing before creating a Jsoup Doc "+  body);
            Document bodyDom = Jsoup.parse(body);
            log.info("printing after creating a Jsoup Doc "+  bodyDom.html());

            Elements preTags = bodyDom.getElementsByTag("pre");

            for (Element pre : preTags) {
                pre.html(pre.html().replaceAll("(\r\n|\n)", "<br />"));
                log.info("Pre element with linebreaks replaced -" + pre);
            }

            body = bodyDom.html();

这是日志,一旦我解析 Jsoup 文档,似乎 html 源代码正在丢失换行符。 :

**2013-12-10 10:14:59 INFO  FormattingTest:166** - printing before creating a Jsoup Doc <p>This is the output:</p>
<pre class="lang-xml prettyprint prettyprinted">
<code><span class="dec">&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&gt;</span><span class="pln">
</span><span class="tag">&lt;HTML&gt;</span><span class="pln">
    </span><span class="tag">&lt;HEAD&gt;</span><span class="pln">
        </span><span class="tag">&lt;META</span><span class="pln"> </span><span class="atn">http-equiv</span><span class="pun">=</span><span class="atv">"Content-Type"</span><span class="pln"> </span><span class="atn">content</span><span class="pun">=</span><span class="atv">"text/html; charset=iso-8859-1"</span><span class="tag">&gt;</span><span class="pln">
        </span><span class="tag">&lt;TITLE&gt;</span><span class="pln">GeteBayOfficialTime</span><span class="tag">&lt;/TITLE&gt;</span><span class="pln">
    </span><span class="tag">&lt;/HEAD&gt;</span><span class="pln">
    </span><span class="tag">&lt;BODY&gt;</span><span class="pln">

* About to connect() to api.ebay.com port 443 (#0)
*   Trying 66.135.211.100... * Timeout
*   Trying 66.135.211.140... * Timeout
*   Trying 66.211.179.150... * Timeout
*   Trying 66.211.179.180... * Timeout
*   Trying 66.135.211.101... * Timeout
*   Trying 66.211.179.148... * Timeout
* connect() timed out!
* Closing connection #0
</span><span class="tag">&lt;P&gt;</span><span class="pln">Error sending request</span></code></pre>


**2013-12-10 10:14:59 INFO  FormattingTest:168** - printing after creating a Jsoup Doc <html>
 <head></head>
 <body>
  <p>This is the output:</p> 
  <pre class="lang-xml prettyprint prettyprinted">
<code><span class="dec">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;</span><span class="pln"> </span><span class="tag">&lt;HTML&gt;</span><span class="pln"> </span><span class="tag">&lt;HEAD&gt;</span><span class="pln"> </span><span class="tag">&lt;META</span><span class="pln"> </span><span class="atn">http-equiv</span><span class="pun">=</span><span class="atv">&quot;Content-Type&quot;</span><span class="pln"> </span><span class="atn">content</span><span class="pun">=</span><span class="atv">&quot;text/html; charset=iso-8859-1&quot;</span><span class="tag">&gt;</span><span class="pln"> </span><span class="tag">&lt;TITLE&gt;</span><span class="pln">GeteBayOfficialTime</span><span class="tag">&lt;/TITLE&gt;</span><span class="pln"> </span><span class="tag">&lt;/HEAD&gt;</span><span class="pln"> </span><span class="tag">&lt;BODY&gt;</span><span class="pln"> * About to connect() to api.ebay.com port 443 (#0) * Trying 66.135.211.100... * Timeout * Trying 66.135.211.140... * Timeout * Trying 66.211.179.150... * Timeout * Trying 66.211.179.180... * Timeout * Trying 66.135.211.101... * Timeout * Trying 66.211.179.148... * Timeout * connect() timed out! * Closing connection #0 </span><span class="tag">&lt;P&gt;</span><span class="pln">Error sending request</span></code></pre>
 </body>
</html>
2013-12-10 10:14:59 INFO  FormattingTest:174 - Pre element with linebreaks replaced -  <pre class="lang-xml prettyprint prettyprinted"><code><span class="dec">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;</span><span class="pln"> </span><span class="tag">&lt;HTML&gt;</span><span class="pln"> </span><span class="tag">&lt;HEAD&gt;</span><span class="pln"> </span><span class="tag">&lt;META</span><span class="pln"> </span><span class="atn">http-equiv</span><span class="pun">=</span><span class="atv">&quot;Content-Type&quot;</span><span class="pln"> </span><span class="atn">content</span><span class="pun">=</span><span class="atv">&quot;text/html; charset=iso-8859-1&quot;</span><span class="tag">&gt;</span><span class="pln"> </span><span class="tag">&lt;TITLE&gt;</span><span class="pln">GeteBayOfficialTime</span><span class="tag">&lt;/TITLE&gt;</span><span class="pln"> </span><span class="tag">&lt;/HEAD&gt;</span><span class="pln"> </span><span class="tag">&lt;BODY&gt;</span><span class="pln"> * About to connect() to api.ebay.com port 443 (#0) * Trying 66.135.211.100... * Timeout * Trying 66.135.211.140... * Timeout * Trying 66.211.179.150... * Timeout * Trying 66.211.179.180... * Timeout * Trying 66.135.211.101... * Timeout * Trying 66.211.179.148... * Timeout * connect() timed out! * Closing connection #0 </span><span class="tag">&lt;P&gt;</span><span class="pln">Error sending request</span></code></pre>

不知道出了什么问题。这与另一个 html 源一起工作 - "\n回应 :\n 一些 xt \n \ndsjkhskjdh sdjhasjkdas \n"

正确转换为 -


响应:
一些文本

dsjkhskjdh sdjhasjkdas

不知道为什么第一个样本没有!!

【问题讨论】:

  • 使用parseBodyFragment 可能会更好,因为您的 HTML 示例不是一个完整的页面。
  • 谢谢,会尝试并通知您。
  • 不幸的是,它没有帮助,它仍然删除所有换行符。

标签: java html jsoup


【解决方案1】:

问题是当你尝试这样做时:

    Jsoup.parse("\nText\nNex").html();

你得到:

    text nex

来自this questions,您可以这样做:

    Document bodyDom = Jsoup.parse(body.replaceAll("(\\r\\n|\\n)", "<br />"));

即在解析文档之前替换换行符。

只替换&lt;pre&gt;标签

如果只替换两个pre 标记之间的换行符,请使用正则表达式提取它们并替换:

    Pattern preP = Pattern.compile("<pre.*?>.+?</pre>", Pattern.DOTALL
            | Pattern.CASE_INSENSITIVE);
    Matcher m = preP.matcher(body);
    while (m.find()) {
        String toReplace = m.group();
        String replaced = toReplace.replaceAll("(\r\n|\n)", "<br />");
        body = body.replace(toReplace, replaced);
    }

.+* 是一个贪婪的限定符,它匹配/pre 的第一次出现,您可以尝试使用正则表达式,但这是不可能的,请参阅this answers 以获得更好的解释。我建议您使用下一个选项。

您可以查看正则表达式here 的示例。

clean解析前的字符串

来自the second asnwers,您可以使用:

    Document.OutputSettings outputSettings = new Document.OutputSettings()
            .prettyPrint(false);
    body = Jsoup.clean(body, "", Whitelist.relaxed(), outputSettings);

之后(如您的原始代码):

    pre.html(pre.html().replaceAll("(\r\n|\n)", "<br />"));

prettyPrint 选项使clean 方法转义换行符,然后解析器正确处理它

干杯

【讨论】:

  • 您好,感谢您的回答。但是,这无济于事,因为 - 如果您查看代码,我希望仅在 Pre 元素内用
    替换换行符。在解析之前用 Jsoup 替换它们将无法达到目的,因为在解析 Pre 元素之前,我将丢失所有换行符。
  • 您好,我添加了更多代码来处理您的案例,在我的本地测试中它有效,如果我错了,请告诉我。干杯
  • 非常感谢您的努力。快速提问,这是否会处理具有任何属性或根本没有属性的 pre 元素?我现在就试一试。
  • 感谢您的回答,正则表达式解决方案运行良好。我现在唯一的问题是,这是否匹配具有任何属性或没有属性的任何 pre 元素?这是否也会处理嵌套的 pre 元素?
  • 嗨 Eswar,带有标签的正则表达式的 .*? 部分使它可以匹配任意数量的属性(并且没有属性)。我现在用嵌套的pre's 尝试它,但它不起作用,我将使用正确的版本更新 mi 答案。另一个大问题是不平衡的pre,正则表达式只匹配平衡的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-21
  • 2011-11-14
  • 1970-01-01
  • 2022-08-07
  • 1970-01-01
相关资源
最近更新 更多