删除大型Java字符串的各个部分(它包含HTML源代码)

时间:2015-08-05 19:31:46

标签: java regex string replace replaceall

在我的应用程序中,我将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()方法生成。

1 个答案:

答案 0 :(得分:1)

1。优雅

  

然而,它并不像是一个优雅的解决方案。

以下是原始正则表达式的两种变体:

变体1

(?s)\s*<!-- this_tag_start([\s\d]+)-->.+?<!-- this_tag_end\1-->\s*

Regular expression visualization

DEMO

此变体使用id的反向引用。我看到的一个缺点是这种变化允许id只是空格。只要您控制评论,这不是一个问题。

变体2

(?s)\s*<!-- this_tag_start\s+(\d+)\s*-->.+?<!-- this_tag_end\s+\1\s*-->\s*

Regular expression visualization

DEMO

此变体再次使用id的反向引用。但是,它更明确的是如何期望id:一个或多个空格,一个或多个数字后跟零个或多个空格。

2。速度

  

应该有更好/更快的方法,对吗?

在内部,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("");
   }

   ...
}