从正则表达式中检索不匹配和匹配的文本

时间:2013-09-12 15:40:44

标签: java regex

我正在尝试搜索可以包含h​​tml和纯文本的Java String。如果html包含单个tick ('<b>'text'<b>')或html块包含三个tick ('''<html><head><title>Sample</title></head><body><div>text</div></body></html>'''),我不需要从String中删除html。如果html没有包含单个或三个tick,那么我需要删除html。

如果内容未混合,以下工作正常。我想修改它,如果 String value="non <b>ticked</b> content <u>here</u> and '<b>'mixed'</b>' content '<u>'here'</u>'将被写入内存/返回non ticked content here and '<b>'mixed'</b>' content '<u>'here'</u>'

我相信我需要更改正则表达式,只将未勾选的(单个或三个)内容传递给我的jsoup html2text方法。有关如何更改正则表达式或逻辑的任何想法,以便只将未打勾的内容传递给html2text方法?如果我将整个字符串(带有勾选的内容)传递给jsoup,它将删除所有不需要的html。

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.jsoup.Jsoup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;

public class HtmlSerializer extends StdSerializer<String> {
  private static final Logger LOG = LoggerFactory.getLogger(HtmlSerializer.class);
  private static final Pattern singlePattern = Pattern.compile("'.*'");
  private static final Pattern blockPattern = Pattern.compile("'''.*'''");

  protected HtmlSerializer() {
    super(String.class);
  }

  @Override
  public void serialize(String value, JsonGenerator jgen, SerializerProvider provider) throws IOException,
      JsonGenerationException {
      if(StringUtils.isNotBlank(value)){
          Matcher blockMatcher = blockPattern.matcher(value);
          Matcher singleMatcher = singlePattern.matcher(value);
          if(!blockMatcher.find() && !singleMatcher.find()){
              jgen.writeString(html2text(value));
          }else{
              jgen.writeString(value);
          }
      }else{
          jgen.writeString(value);
      }  
  }

  private static String html2text(String html) {
        return Jsoup.parse(html).text();
    }
}

1 个答案:

答案 0 :(得分:2)

您的模式无法正常运行,因为.*尽可能匹配。因此'.*'将从'的第一次出现到'的最后一次出现匹配,无论其间有多少'。在您的示例中,它将匹配整个序列'<b>'mixed'</b>' content '<u>'here'</u>'

要解决这个问题,最简单的方法就是使用“不情愿的量词”。 (http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#sum'.*?'会尽可能少地匹配,因此会在'的下一次出现时停止。

这同样适用于您的群组语法,请使用'''.*?'''。然后,您可以将它们与操作结合使用,以查找所有引用的构造:'''.*?'''|'.*?'。首先指定三重引号很重要,因为它们会被视为多个单引号字符串。

然后处理必须像这样处理子串

Pattern p=Pattern.compile("'''.*?'''|'.*?'");
Matcher m=p.matcher(value);
int normalPos=0, length=value.length();
while(normalPos<length && m.find())
{
  int quotePos=m.start(), quoteEnd=m.end();
  if(normalPos<quotePos) processNormally(value.substring(normalPos, quotePos));
  final boolean tripleQuote=m.end()-m.start()>=6 && value.charAt(quotePos+1)=='\'';
  final int skip=tripleQuote? 3: 1;
  processQuoted(value.substring(quotePos+skip, quoteEnd-skip));
  normalPos=quoteEnd;
}
if(normalPos<length) processNormally(value.substring(normalPos));