首页 > 解决方案 > 如何使用 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
  //    (<[^>]+>)+&nbsp;(</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|![)[^>]*?>?|"
        + "(<[^>]+>)+&nbsp;(</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|![)[^>]*?>?|(<[^>]+>)+&nbsp;(</w+>)+?

有人可以请告诉我正确的语法吗?

Wiktor 提供了一个很好的答案;但是颜色样式已被删除,如果可能的话,我想保留它。

清洁前:

notClean: <p class="MsoNormal"><b><span lang="EN-AU" style="font-size:11.0pt;font-family:&quot;Verdana&quot;,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">&nbsp;</span></b></p><p class="MsoNormal"><b><span lang="EN-AU">&nbsp;</span></b></p><p>

</p><p class="MsoNormal"><b><i><span lang="EN-AU" style="font-size:11.0pt;font-family:&quot;Verdana&quot;,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:&quot;Verdana&quot;,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|!\\[)[^>]*>|"
            + "(<[^>]+>)+&nbsp;(</\\w+>)+", Pattern.CASE_INSENSITIVE|Pattern.DOTALL);

但是,样式仍然被删除。

我也不得不离开“跨度”。

标签: javahtmlregex

解决方案


您可以使用

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|!\\[)[^>]*>|"
        + "(<[^>]+>)+&nbsp;(</\\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 可选。

推荐阅读