我正在尝试创建一个正则表达式来从我们的文档站点中提取两个 anchor 标记之间的内容。
让我们以JDK wiki page为例举个例子。我想提取“JDK 内容”和“JDK 与 SDK 之间的歧义”之间的内容。我当前的正则表达式是:
<span[^>]*\bid\s*=\s*(?:"|')?JDK_contents(?:'|")?[^>]*>([^<]*)</span>(.*?)
(<span[^>]*\bid\s*=\s*(?:"|')?Ambiguity_between_a_JDK_and_an_SDK(?:'|")?[^>]*>[^<]*</span>.*)
但由于这种正则表达式会被多次执行,所以我想对其进行优化。
我可以考虑的一件事是 .*?: </span>(.*?)(<span[^>]...)
因为它会匹配任何东西,并导致很多回溯。
顺便说一句,我也试过贪心版:</span>(.*)(<span[^>]...)
, 但它比 .*
慢得多将匹配所有文本,然后回溯到 Ambiguity_between_a_JDK_and_an_SDK
跨度。
我正在使用 Java。谁能帮忙提供一些见解?
最佳答案
您可以使用 Jsoup 的 css 选择器实现相同的效果。
解决方案
h2:has(span#JDK_contents) ~ *:not(h2:has(span#Ambiguity_between_a_JDK_and_an_SDK) ~ *):not(h2)
描述
为清楚起见,我们将 h2Start
称为一个 h2 标签,该标签至少有一个 id 为 JDK_contents 的 span。我们也将 h2End
称为一个 h2 标签,它至少有一个 span 的 ID 为 Ambiguity_between_a_JDK_and_an_SDK。
h2:has(span#JDK_contents) /* Select an h2Start */
~ * /* Select any node preceded by this h2Start... */
:not(h2:has(span#Ambiguity_between_a_JDK_and_an_SDK) ~ *) /* ...but not peceded by an h2End */
:not(h2) /* We remove h2End */
注意:
在 JDK wiki page 的情况下, 最后一行就够了。更严格地说,我们会将其替换为 :not(h2:has(span#Ambiguity_between_a_JDK_and_an_SDK))
。
关于java - 优化 Regex 以提取两个标签之间的内容(或 How to select content between two tags with Jsoup selector API?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21511321/