在我的应用程序中,我将HTML源页面加载到String中。在此HTML中,我想删除特定HTML注释之间的某些内容。
例如:
//the entire String will be HTML source like this, of the entire page
<div id="someid">
<a href="#">Some text</a>
<!-- this_tag_start 123 -->
<p> This text between the tags to be removed </p>
<!-- this_tag_end 123 -->
<a href="#">Some text</a>
</div>
那this_tag_start 123
和相应的&#34;结束&#34;一个是由我们的服务器生成的。 123
号码会有所不同。
在我的程序中,我有一个包含整个HTML源代码的String。我想删除这两个注释标记之间的文本(如果注释标记保留或不存在则无关紧要)。这些HTML注释标记可以在整个HTML源中出现不同的时间。
现在我正在使用此正则表达式删除内容:
htmlString = htmlString.replaceAll(
"<!-- this_tag_start(.*?)<!-- this_tag_end[\\s\\d]+-->",""
);
这样可以正确删除这些注释标记以及开始和结束标记之间的内容。但是,它并不是一个优雅的解决方案。应该有更好/更快的方法,对吗?
如果重要,String由WebDriver的getPageSource()方法生成。
答案 0 :(得分:1)
然而,它并不像是一个优雅的解决方案。
以下是原始正则表达式的两种变体:
(?s)\s*<!-- this_tag_start([\s\d]+)-->.+?<!-- this_tag_end\1-->\s*
此变体使用id的反向引用。我看到的一个缺点是这种变化允许id只是空格。只要您控制评论,这不是一个问题。
(?s)\s*<!-- this_tag_start\s+(\d+)\s*-->.+?<!-- this_tag_end\s+\1\s*-->\s*
此变体再次使用id的反向引用。但是,它更明确的是如何期望id:一个或多个空格,一个或多个数字后跟零个或多个空格。
应该有更好/更快的方法,对吗?
在内部,String#replaceAll
方法会调用Pattern#compile
。众所周知,模式编译是慢。
我会缓存编译结果以便更快地替换。 以下是如何做到这一点:
public class MyCrawler {
// Compile once, run multiple times
private static final Matcher COMMENT_REMOVER = Pattern.compile("the regex here...").matcher("");
public void doCrawl() {
String htmlString = loadHtmlSource();
htmlString = COMMENT_REMOVER.reset(htmlString).replaceAll("");
}
...
}