如何使用 java regex 删除 MS Word 不必要的 html 标签

Posted

技术标签:

【中文标题】如何使用 java regex 删除 MS Word 不必要的 html 标签【英文标题】:How to remove MS Word unnecessary html tags using java regex 【发布时间】:2021-03-04 12:09:50 【问题描述】:

我有一个所见即所得的编辑器,有时用户会从 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);

但是,样式仍然被删除。

我也不得不留下“跨度”。

【问题讨论】:

【参考方案1】:

你可以使用

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 demo。

注意事项

Pattern.DOTALL 使 . matcb 包括换行符在内的任何字符(因此无需使用像 [\w\W] 这样的解决方法) 不要忘记在正则表达式转义中转义反斜杠,例如 \s\w(在 Java 字符串文字中,"\\s""\\w") 不要忘记转义特殊的正则表达式元字符,例如[(,请参阅What special characters must be escaped in regular expressions? 如果字符串中必须存在 char,请不要在其后面加上 ?(就像您的模式中的 &gt; 一样),这会使 char 成为可选字符。

【讨论】:

你好维克托,谢谢。不过,我对此有一个问题。颜色格式被删除。我已经在我的问题中添加了之前和之后,因此它的格式正确。有没有办法保持“风格”?我尝试了上述方法。 @Glyn 抱歉,我不明白:如果您想保留所有样式,请删除 |\\s+style='[^']+' 和其他与“样式”有关的内容。 嗨 Wiktor,从我的编辑中你会看到有一个 "style="font-size:11.0pt;font-family:"Verdana",sans-serif;color:#006600""在被删除的原件中。这包含“颜色:#006600”。我可以保留所有的“style= ....”吗?如果不是(即会破坏 html),那么我可以只保留颜色“style=color:#006600;”吗?我相信它应该以 ;)? 结尾? 嗨,Wiktor,我发现这是我需要离开的“跨度”。我会监控看看这是否会导致任何问题。非常感谢您的帮助!【参考方案2】:

我相信你需要转义特殊字符&lt;([\^-=$!|])?*+.&gt;

Here is a link with more info.

【讨论】:

以上是关于如何使用 java regex 删除 MS Word 不必要的 html 标签的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MS 访问中运行 Regex(如果支持)? [复制]

如何使用 Regex.Replace 从字符串中删除数字?

Java:String.replace(regex, string) 从 XML 中删除内容

如何通过java将多个word文档合成一个wor

使用 Python 和 Regex,如何从 html 中删除 <sup> 标签? [复制]

带有regex的ReplaceAll删除了Java不想删除的一个多余的字符