(1)Pattern pt=Pattern.compile("<//s*body[^>]*>.*?<//s*/body//s*>", Pattern.CASE_INSENSITIVE |Pattern.DOTALL);
Matcher mt=pt.matcher(htmlContent);
while(mt.find()){
String content = mt.group();
content = content.replaceAll("<//s*body[^>]*>", "").replaceAll("<//s*/body//s*>", "").replaceAll("/r|/n", "");
if(content.matches("//s*(<//s*p[^>]*>)*( )*//s*(null)*//s*( )*(<//s*/p>)*//s*"))
return true;
}
如果用以下语句的话:
(2)Pattern pt=Pattern.compile("<//s*body[^>]*>(.|/n|/r)*?<//s*/body//s*>", Pattern.CASE_INSENSITIVE );
Matcher mt=pt.matcher(htmlContent);
while(mt.find()){
String content = mt.group();
content = content.replaceAll("<//s*body[^>]*>", "").replaceAll("<//s*/body//s*>", "").replaceAll("/r|/n", "");
if(content.matches("//s*(<//s*p[^>]*>)*( )*//s*(null)*//s*( )*(<//s*/p>)*//s*"))
return true;
}
但内容足够大时,因为mt.group();是通过递归查询符合正规的字符,但(.|/n|/r)*?是通过三个分支查找,当内容足够大
而内在不够大时会造成内存溢出,因此用语句(1)的表达式做正规匹配一次性匹配更可以提高性能,也不会造成内存溢出
Pattern.CASE_INSENSITIVE——启用不区分大小写的匹配。(? i)
Pattern.COMMENTS——允许在模式中使用空白和注释。(? x)
Pattern.DOTALL——启用dotall模式。在dotall模式下,表达式.匹配任何字符,包括行终止符。默认情况下,这个表达式不匹配行终止符。(? s)
Pattern.LITERAL——启用模式的字面量解析。指定了这个标志时,指定模式的输入字符串被当作字面量字符的序列。输入序列中的元字符或者转移 序列没有特殊含义。和这个标志结合使用时,标志CASE_INSENSITIVE和UNICODE_CASE保留它们对匹配的影响。
Pattern.MULTILINE——启用多行模式。在多行模式下,表达式^和$分别正好在行终止符或者输入序列的末尾的之前或者之后。默认情况下,这些表达式只匹配整个输入序列的开头和结尾。也可以通过嵌入标志表达式(? m)启动多行模式。
嵌入标志表达式
常 量 | 等效的嵌入标志表达式 |
Pattern.CANON_EQ | 无 |
Pattern.CASE_INSENSITIVE | (?i) |
Pattern.COMMENTS | (?x) |
Pattern.MULTILINE | (?m) |
Pattern.DOTALL | (?s) |
Pattern.LITERAL | 无 |
Pattern.UNICODE_CASE | (?u) |
Pattern.UNIX_LINES | (?d) |