当前位置: 首页 > 知识库问答 >
问题:

使用jsoup或regex在标题标记之间提取html标记

邹高懿
2023-03-14

嗨,我有一个html文件解析的场景。我正在使用jsoup解析html文件,解析后我想提取头标记(h1、h3、h4)。我用过医生。select()但它将只返回标题标记值,但我的要求是我应该提取h1到h3或h4之间的标记,反之亦然。

<h4>SECTION 2</h4>
<p>some thing h4.....</p>
<p>some thing h4.....</p>
<p>some thing h4.....</p>
<h3>lawsuit</h3>
<p>some thing h3.....</p>
<p>some thing h3.....</p>
<p>some thing h3.....</p>
<h1>header one </h1>

所以这里首先搜索html字符串是否包含任何H1,H3,H4。这里我们有h4,所以包括h4,它应该搜索下一个h1或h3,直到h3我们提取字符串并把它放在一个单独的html文件中。

第一个html文件包含

<h4>SECTION 2</h4>
<p>some thing h4.....</p>
<p>some thing h4.....</p>
<p>some thing h4.....</p>

第二个html文件包含

<h3>lawsuit</h3>
<p>some thing h3.....</p>
<p>some thing h3.....</p>
<p>some thing h3.....</p>

第三个html文件包含

<h1>header one </h1>
....
....
....

这里的html字符串是动态的,所以我想写一个正则表达式来实现这个上下文,因为我是java新手,不知道如何实现。现在我使用了子字符串,但我需要一种通用方法,要么是正则表达式,要么是jsoup本身。

我试过的代码是。

try {
    File sourceFile = new File("E://data1.html");
    org.jsoup.nodes.Document doc = Jsoup.parse(sourceFile, "UTF-8");
    org.jsoup.nodes.Element elements = doc.body();
    String elementString = StringUtils.substringBetween(elements.toString(),"<h4>", "<h3>");
    System.out.println("elementString::"+elementString);
    File destinationFile = new File("E://sample.html");
    BufferedWriter htmlWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destinationFile), "UTF-8"));
    htmlWriter.write(elementString);
    htmlWriter.close();
    System.out.println("Completed!!!");
} catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

请帮助我实现这一目标。

共有2个答案

孟智志
2023-03-14

你可能正在寻找这个。您可以在选择所需元素后使用此函数。

如果您使用的是JSoup,在dom操作的情况下,您不必(事实上不需要)使用regex。

Elements heads = body.select('h1');
// iterate and get inner html of that elements by
String html = head.html();

--编辑--

误解了问题;

您可以确定h标签的索引,并使用getElementsByIndexGreaterthan。其余的将是一样的。

--编辑2--

针对您的具体情况;您可以在找到第一个h元素后进行迭代:

  Elements elements = doc.select("h1,h2,h3,h4,h5");
  for (Element element : elements) {
     StringBuilder sb = new StringBuilder(element.toString());

     Element next = element.nextElementSibling();
     while (next != null && !next.tagName().startsWith("h")) {
        sb.append(next.toString()).append("\n");
        next = next.nextElementSibling();
     }
     System.out.println(sb);

  }

应该对你有用。

仲孙献
2023-03-14

请不要使用正则表达式从Xml或HTML文档中提取元素。Regex对大型文档有限制。

改为使用XPath查询文档。例如,试着看看这个stackoverflow问题。可以使用管道运算符|在OR中具有多个条件。

类似的方法应该可以奏效:

//h1/following-sibling::p |
//h2/following-sibling::p |
//h3/following-sibling::p |
...
 类似资料:
  • 在像这样的网站上http://wikitravel.org/en/San_Francisco,诸如“Districts”、“Understand”、“Get in”等部分实际上并不包含HTML中的整个部分。节实际上只是标题中的跨类。正因为如此,我们不能简单地通过选择id来获取wiki文档的某些部分。 但是,是否可以收集两个标记之间的所有html?比如说我想要“四处走动”部分。我该如何发出一个选择器

  • 我有这个html 并且,我试图得到每个标签的href。 例如,

  • 我实际上正在用Java开发一个文本解析器,有人要求我通过用它解析HTML来增强它。解析器的目的是将被解析的文件分成另外三个文件,一个包含文件中包含的所有单词,一个包括所有句子,另一个包含所有问题。 *.txt部分工作得很好,但我在解析HTML时遇到了一个问题。 我创建了一个扩展名为*.txt的临时文件,并将其在我的文本解析器中传递,但是如果我传递一个带有HTML文件链接的URL,其格式如下所示:

  • 这是我的密码 我想替换字体标签,并把span标签。在这将取代第一个字体标签但不是第二个标签

  • 我正在尝试从 html 标签中提取字符串 我知道还有其他类似或甚至相同的问题得到了回答,但这些问题的答案似乎对我不起作用 此输出 不 注意,我使用了来自不同答案的其他正则表达式,得到了相同的结果,我也不熟悉正则表达式,所以这可能是一个无意义的问题。