我正在尝试搜索可以包含html和纯文本的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();
}
}
答案 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));