我无法使用 Jsoup Java 库解析以下场景的某些文本。
1:This is <b>My Text</b> some other <b> </b> text as well <b></b><b>non empty tag1</b> other text
.
预期输出: some other <b> </b> text as well <b></b>
2:This is <b>My Text</b> some other <b> </b> text as well <b></b><b>non empty tag2</b> other text
.
预期输出: some other <b> </b> text as well <b></b>
3:This is <b>My Text</b> some other <b> </b> text as well <b></b><b>non empty tag2</b> other text <b></b> <b>non empty tag3</b>
.
预期输出: some other <b> </b> text as well <b></b>
在这里,如果您注意到文本我的文本是固定的(静态),但第二个非空(不将空格视为值)B标签值可能会有所不同。正则表达式应该能够提取 <b>My Text</b>
之间的文本。第一次出现非空 <b>
之后标记。
我正在使用 Jsoup 库,但无法实现上述预期输出。请确保该解决方案对于每个场景都应该是通用的,因为在我的例子中它是动态的。
最佳答案
简单的解决方案可能看起来像
- 查找
<b>
您感兴趣的元素(包含您要查找的文本的元素) - 迭代放置在其后面的同级并打印它们,直到找到非空
<b>
您只需要记住 Jsoup 正在使用 Node
存储所有元素(包括不属于标签的文本),而 Element
类(扩展 Node
)可能只包含特定标签。
例如像
这样的文本before <b>bold</b> after<i>italic</i>
将表示为
<node>before </node>
<element tag="B">
<node>bold</node>
</element>
<node> after</node>
<element tag="I">
<node>italic</node>
</element>
例如,如果您 select("b")
(它将找到 <element tab="B">
)并调用 nextElementSibling()
它会将您移至<element tag="I">
。获取<node>after</node>
您将需要使用nextSibling()
这并没有消除简单的文本节点。
Node
可能存在问题类的问题是它不提供 text()
可以生成当前节点文本内容的方法(这可以让我们测试当前节点/元素是否有任何文本)。但没有什么能阻止我们类型转换 Node
它将标签处理为 Element
提供了这样的方法。
所以我们的解决方案可能如下所示:
public static String findFragment(String html, String fixedStart) {
Document doc = Jsoup.parse(html);
Element myBTag = doc
.select("b:matches(^" + Pattern.quote(fixedStart) + "$)")
.first();
StringBuilder sb = new StringBuilder();
boolean foundNonEmpty = false;
Node currentSibling = myBTag.nextSibling();
while (currentSibling != null && !foundNonEmpty) {
if (currentSibling.nodeName().equals("b")) {
Element b = (Element) currentSibling;
if (!b.text().trim().isEmpty())
foundNonEmpty = true;
}
sb.append(currentSibling.toString());
currentSibling = currentSibling.nextSibling();
}
return sb.toString();
}
关于java - 无法使用 Jsoup HTML 解析器 Java 实现某些功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37692739/