java - JSoup:替换字符串会添加新行

标签 java jsoup

我在使用 JSoup 时遇到以下问题。

我想解析并修改以下html代码:

<code>
<style type="text/css" media="all">
@import url("http://hakkon-aetterni.at/modules/system/system.base.css?ll3lgd");
@import url("http://hakkon-aetterni.at/modules/system/system.menus.css?ll3lgd");
@import url("http://hakkon-aetterni.at/modules/system/system.messages.css?ll3lgd");
@import url("http://hakkon-aetterni.at/modules/system/system.theme.css?ll3lgd");

  </style> 
</code>

我使用以下代码来实现这一目标:

Elements cssImports= doc.select("style");
        for (Element src : cssImports) {
            String regex ="url\\(\"(.)*\"\\)";
            String data =src.data();
            String link;        

            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(data);

            while (m.find()){
                link=m.group().substring(5,m.group().length()-2);
                doc=Jsoup.parse(doc.html().replace(link, ""));
            }
        }

首先,它有效。所有导入 URL 均替换为字符串“FOUND”。我遇到的问题是在最后一个 import 语句和关闭的 </style> 之间有很多新行。标记以前不存在的位置。

有任何线索说明为什么会发生这种情况以及如何避免这种情况吗?

很抱歉格式错误,但我的代码的某些部分似乎在发布时被删除了。第一个代码块周围有一个样式标签...

最佳答案

好吧,我今天登陆这个页面,想做一件非常类似的事情,我相信我已经解决了它。希望一个月后还有人在看这个。 ;)

我发现效果很好的是,不是在每个循环上进行字符串替换和重新解析文档,而是重建 style 元素的内容。 JSoup 真正闪光的地方之一是它的 API 使编辑解析文档变得多么容易。

另一个技巧是使用 data() 函数。 JSoup 区分数据(例如 scriptstyle)和 html/text 节点。主要区别在于 HTML 转义应用于数据节点。

将所有这些放在一起,以下代码片段应将导入的样式表引用替换为 FOUND 文本,但不更改文档的格式:

// compile the regex before entering the loop, as it's a relatively expensive operation
Pattern pattern = Pattern.compile("url\\(\"(.)*\"\\)");
for(Element styleElem : doc.getElementsByTag("style")) {

    String data = styleElem.data();
    StringBuffer newData = new StringBuffer();
    Matcher matcher = pattern.matcher(data);

    while(matcher.find()) {
        matcher.appendReplacement(newData, "FOUND");
    }
    matcher.appendTail(newData);

    styleElem.appendChild(new DataNode(newData.toString(), base.toExternalForm()));
}

附注我假设你已经关闭了 pretty-print 。不过,由于未显示文档解析代码,因此请务必在解析后调用 document.outputSettings().prettyPrint(false);

P.P.S。在我自己的代码中,我使用更宽容(并且稍微丑陋)的正则表达式来查找导入。它让用户可以省略 URL 声明、引号、括号等……因为野外的 HTML 往往会做所有这些事情。我在代码中声明了它,如下所示:

public static final Pattern CSS_IMPORT_PATTERN = Pattern.compile("(@import\\s+(?:url)?\\s*\\(?\\s*['\"]?)(.*?)([\\s'\";,)]|$)");

关于java - JSoup:替换字符串会添加新行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6042558/

相关文章:

java - JAXB 与 JDOM : is it possible to update xml file using JAXB

java - 在 JSON 中追加或删除数据

java - 根据 Stream api 的条件将列表拆分为子列表

java - Java LinkedBlockingQueue 中的非 volatile 头尾引用

java - 比较字符串的字符是否存在于字符数组中

java - 奇怪的 java.lang.ExceptionInInitializerError - JSoup

java - 使用 Jsoup 抓取网页

带代理的Java多线程post方法(使用Jsoup)

java - GWT RegExp - 多个匹配

java - 在 JAVA 中使用 JSOUP 从 HTML 中提取 CSS 样式