使用正则表达式删除 JavaScript

Posted

技术标签:

【中文标题】使用正则表达式删除 JavaScript【英文标题】:Remove JavaScript with Regex 【发布时间】:2011-12-23 21:23:51 【问题描述】:

我无法使用 C# 从 html 页面中删除所有 javascript。我有三个正则表达式删除了很多但也错过了很多。使用 MSHTML DOM 解析器解析 javascript 会导致 javascript 实际运行,这是我试图通过使用正则表达式来避免的。

    "<script.*/>"

    "<script[^>]*>.*</script>"

    "<script.*?>[\\s\\S]*?</.*?script>"

有谁知道我缺少什么导致这三个正则表达式缺少 JavaScript 块?

我要删除的示例:

<script src="do_files/page.js" type="text/javascript"></script>
<script src="do_files/page.js" type="text/javascript" />
    <script type="text/javascript">
    <!--
        var Time=new Application('Time')
    //-->
    </script>
    <script type="text/javascript">
        if(window['com.actions']) 
            window['com.actions'].approvalStatement =  "",
            window['com.actions'].hasApprovalStatement = false
        
    </script>

【问题讨论】:

你能举一个错过区块的例子吗? 使用 HTML 解析器(如 Nokogiri)并修改 DOM; do not use a regex 在原始 HTML 上。您是尝试在 Web 浏览器客户端还是在服务器上执行此操作?如果是服务器,什么编程语言? 如果有的话,看起来你的正则表达式会比你想要的匹配更多。你的 #2 正在做一个贪婪的 .*,所以它会匹配从页面上的第一个 &lt;script&gt; 到最后一个 &lt;/script&gt; 的所有内容,可能包括你没有的内容 between 脚本标签意思是删除。 语言是 C#。使用 mshtml 解析器实际上运行 java 脚本,这是我试图通过首先删除它来避免的。 Regex 对 PARSING HTML 不是特别好——但那是因为 HTML 允许嵌套构造(如 &lt;span&gt;&lt;b&gt;&lt;i&gt;&lt;u&gt;hello &lt;span class="mundo"&gt;world&lt;/span&gt;&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;)脚本标签基本上没有嵌套,所以它远不及相关的(注释或 CDATA 标记经常在脚本标记中使用,但这些都不是一个不容忽视的挑战)。 REMOVING 或 STRIPPING HTML 稍有不同,因为表达式的复杂性可以大大降低。 【参考方案1】:

我假设您正在尝试简单地清理 JavaScript 的输入。坦率地说,我担心这是一个过于简单的解决方案,因为它看起来非常简单。在表达式之后(在 C# 字符串中),请参见下面的推理:

@"(?s)<script.*?(/>|</script>)"

就是这样 - 我希望! (它当然适用于您的示例!)

我之所以简单的原因是,尝试使用正则表达式解析 HTML 的主要问题是嵌套标签的可能性——与其说是不同标签的嵌套,不如说是同义标签的嵌套

例如,

<b> bold <i> AND italic </i></b>

...还不错,但是

<span class='BoldText'> bold <span class='ItalicText'> AND italic </span></span>

会更难解析,因为结束标签是相同的。

但是,由于嵌套script标签是无效的,/&gt;(</script>的下一个实例是这个脚本块的结尾。

脚本标签中总是有可能包含 HTML cmets 或 CDATA 标签,但如果它们不包含 &lt;/script&gt; 应该没问题。但是:如果他们这样做,肯定有可能通过一些“代码”。我不认为页面会呈现,但是一些 HTML 解析器非常灵活,所以你永远不会知道。要处理一些额外的可能空格,您可以使用:

@"(?s)<\s?script.*?(/\s?>|<\s?/\s?script\s?>)"

请告诉我你是否能想出一种方法来打破它,让 VALID HTML 代码使用可运行的 JavaScript(我知道有几种方法可以得到 一些 东西通过,但如果它通过了,它应该以许多不同的方式之一被破坏,并且不应该是可运行的 JavaScript 代码。)

【讨论】:

当然,这应该处理所有有效脚本块的完全删除,并且有效的 HTML 输入应该是有效的 HTML 输出(减去脚本块) 太棒了!非常感谢。【参考方案2】:

人们普遍认为,尝试使用正则表达式解析 HTML 是一个坏主意,并且会产生不好的结果。相反,您应该使用 DOM 解析器。 jQuery 很好地包裹了浏览器的 DOM,并允许您非常轻松地删除所有 &lt;script&gt; 标记。

【讨论】:

嘿。我喜欢使用 jQuery 删除 JavaScript 的讽刺意味。 HTML Agility Pack 似乎是标准的 C# 解决方案。【参考方案3】:

好的,当我需要从任何可能的 javascript-ing 中清除“富文本”(具有 HTML 格式的文本)时,我也遇到过类似的情况。

有几种方法可以将 javascript 添加到 HTML:

通过使用

通过在 HTML 元素上使用事件,例如“onload”或“onmouseover” 例如:

通过创建调用 javascript 代码的超链接 例如:...

暂时能想到的就这些了。

所以提交的 HTML 代码需要从这 3 种情况中清除。一个简单的解决方案是使用 Regex 查找这些模式,并将它们替换为 "" 或做任何你想做的事情。

这是一个简单的代码:

public static string CleanHTMLFromScript(string str)

    Regex re = new Regex("<script[^>]*>", RegexOptions.IgnoreCase);
    str = re.Replace(str, "");
    re = new Regex("<[a-z][^>]*on[a-z]+=\"?[^\"]*\"?[^>]*>", RegexOptions.IgnoreCase);
    str = re.Replace(str, "");
    re = new Regex("<a\\s+href\\s*=\\s*\"?\\s*javascript:[^\"]*\"[^>]*>", RegexOptions.IgnoreCase);
    str = re.Replace(str, "");
    return(str);

此代码负责处理可能添加或不添加的任何空格和引号。它似乎工作正常,并不完美,但它确实有效。欢迎任何改进。

【讨论】:

【参考方案4】:

如果这样做是为了防止跨站点脚本,那么创建自己的 HTML 解析器或脚本检测器是一个特别糟糕的主意。手动执行此操作是一个非常糟糕的主意,因为有许多极端情况和技巧可用于击败此类尝试。这被称为“黑名单”,因为它试图从 HTML 中删除不安全的项目,而且几乎注定要失败。

使用白名单处理器(例如AntiSamy)要安全得多,它只会通过自动转义其他所有内容来允许已批准的项目通过。

当然,如果这不是您正在做的事情,那么您可能应该编辑您的问题以提供更多背景信息...

编辑:

既然我们知道您正在使用 C#,请按照建议的 here 尝试 HTMLAgilityPack。

【讨论】:

我过去曾遇到过敏捷包中的错误,因此我倾向于远离它……但感谢您的建议。【参考方案5】:

您使用哪种语言?一般来说,正则表达式不适合解析 HTML。

如果您在 .net 平台上,HTML Agility Pack 提供了更好的解析器。

【讨论】:

【参考方案6】:

您应该使用真正的 html 解析器来完成这项工作。话虽这么说,对于简单的剥离 脚本块,您可以使用如下的基本正则表达式。

这个想法是您需要一个回调来确定捕获组 1 是否匹配。 如果是这样,回调应该将隐藏 html 的东西(如 cmets)传回 通过不变,脚本块作为空字符串传回。

不过,这不会替代 html 处理器。祝你好运!

搜索正则表达式:(修饰符 - 扩展的、全局的、在点中包含换行符、回调函数)

  (?:
     <script (?:\s+(?:".*?"|\'.*?\'|[^>]*?)+)? \s*> .*? </script\s*>
   | </?script (?:\s+(?:".*?"|\'.*?\'|[^>]*?)+)? \s*/?>
  )
|
  (   # Capture group 1
    <!(?:DOCTYPE.*?|--.*?--)>  # things that hide html, add more constructs here ...
  )

替换func伪代码:

string callback () 
  if capture buffer 1 matched
    return capt buffer 1
  else return ''

【讨论】:

以上是关于使用正则表达式删除 JavaScript的主要内容,如果未能解决你的问题,请参考以下文章

Javascript - 正则表达式从标题中删除特殊字符

JavaScript 正则表达式 - 从开头和结尾删除空格

Javascript 正则表达式逗号检测不起作用

使用正则表达式删除注释

使用正则表达式删除注释

使用正则表达式删除注释