java - 如何使用 java regex 删除 MS Word 不必要的 html 标签
问题描述
我有一个所见即所得的编辑器,有时用户会从 MS Word 中剪切和粘贴。在我的服务器端java中,我试图从粘贴的html中删除不必要的html,例如:
<o:p>
应该:
<p>
我试图删除的模式是:
//Remove:
// unnecessary tag spans (comments and title)
// <!--(w|W)+?-->
// <title>(w|W)+?</title>
//classes and styles
// s?class=w+
// s+style='[^']+'
//unnecessary tags
// <(meta|link|/?o:|/?style|/?div|/?std|/?head|/?html|body|/?body|/?span|![)[^>]*?>
//empty paragraph tags
// (<[^>]+>)+ (</w+>)+
//bizarre v: element attached to <img> tag
// s+v:w+=""[^""]+""
我的代码是:
Pattern p = Pattern.compile("<!--(w|W)+?-->?|<title>(w|W)+?</title>?|s+style='[^']+'?|"
+ "<(meta|link|/?o:|/?style|/?div|/?std|/?head|/?html|body|/?body|/?span|![)[^>]*?>?|"
+ "(<[^>]+>)+ (</w+>)+?", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(html);
String result = m.replaceAll("");
我得到错误:
java.util.regex.PatternSyntaxException: Unclosed character class near index 163
<!--(w|W)+?-->?|<title>(w|W)+?</title>?|s+style='[^']+'?|<(meta|link|/?o:|/?style|/?div|/?std|/?head|/?html|body|/?body|/?span|![)[^>]*?>?|(<[^>]+>)+ (</w+>)+?
有人可以请告诉我正确的语法吗?
Wiktor 提供了一个很好的答案;但是颜色样式已被删除,如果可能的话,我想保留它。
清洁前:
notClean: <p class="MsoNormal"><b><span lang="EN-AU" style="font-size:11.0pt;font-family:"Verdana",sans-serif;color:#006600">Special
Interest Area badges youth members can achieve, supported by Queensland
Environmental Education Team:<o:p></o:p></span></b></p><p class="MsoNormal"><b><span lang="EN-AU"> </span></b></p><p class="MsoNormal"><b><span lang="EN-AU"> </span></b></p><p>
</p><p class="MsoNormal"><b><i><span lang="EN-AU" style="font-size:11.0pt;font-family:"Verdana",sans-serif">Joey Scout SIA Badges
(2 hours each badge)</span></i></b><b><span lang="EN-AU" style="font-size:11.0pt;font-family:"Verdana",sans-serif"><o:p></o:p></span></b></p>
清洁后:
cleaned: <p class="MsoNormal"><b>Special
Interest Area badges youth members can achieve, supported by Queensland
Environmental Education Team:<p>
</p><p class="MsoNormal"><b><i>Joey Scout SIA Badges
(2 hours each badge)</i></b><b></b></p>
我试过了:
Pattern p = Pattern.compile("<!--.*?-->|<title>.*?</title>|"
+ "<(meta|link|/?o:|/?div|/?std|/?head|/?html|/?body|/?span|!\\[)[^>]*>|"
+ "(<[^>]+>)+ (</\\w+>)+", Pattern.CASE_INSENSITIVE|Pattern.DOTALL);
但是,样式仍然被删除。
我也不得不离开“跨度”。
解决方案
您可以使用
String html = "Cleaned!<!-- \nsome comment --><title> my title</title> style='OUR_STYLE'<meta ...>";
Pattern p = Pattern.compile("<!--.*?-->|<title>.*?</title>|\\s+style='[^']+'|"
+ "<(meta|link|/?o:|/?style|/?div|/?std|/?head|/?html|/?body|/?span|!\\[)[^>]*>|"
+ "(<[^>]+>)+ (</\\w+>)+", Pattern.CASE_INSENSITIVE|Pattern.DOTALL);
Matcher m = p.matcher(html);
String result = m.replaceAll("");
System.out.println(result);
// => Cleaned!
请参阅Java 演示。
注意事项:
Pattern.DOTALL
使.
matcb 包括换行符在内的任何字符(因此无需使用类似的解决方法[\w\W]
)- 不要忘记在正则表达式转义中转义反斜杠,例如
\s
或\w
(在 Java 字符串文字中,"\\s"
或"\\w"
) - 不要忘记转义特殊的正则表达式元字符,例如
[
or(
,请参阅在正则表达式中必须转义哪些特殊字符? - 如果字符串中必须存在 char,请不要放在
?
它后面(就像>
您的模式中的情况一样),它会使 char 可选。
推荐阅读
- sql - 对每 n 个和组的 SQL 行求和
- python - 使用 BRISQUE 特征检测放大图像
- mysql - 使用两个表的列之间的外部映射连接 mysql 中的两个表
- java - 重构方法引用以支持参数
- php - SQLSTATE [HY000]:一般错误:1364 字段“contactId”没有默认值
- php - Symfony - 参数语法和重定向
- python - 在 Pytest 中收集测试结果数据
- postgresql - 如何在线使用geoserver + postgresql?
- linux - Linux 服务应用程序创建文件的权限
- javascript - 如何将数组划分为具有灵活输出长度的块?