我在使用 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 区分数据(例如 script
和 style
)和 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/