使用JS Regular Expression从html中删除所有脚本标记

时间:2011-07-12 04:01:50

标签: javascript html regex

我想在pastebin

中删除这个html的脚本标签
  

http://pastebin.com/mdxygM0a

我尝试使用以下正则表达式

html.replace(/<script.*>.*<\/script>/ims, " ")

但它不会删除html中的所有脚本标记。它只删除内联脚本。请我需要一个可以删除所有脚本标签的正则表达式(内联和多行)。如果对我的样本http://pastebin.com/mdxygM0a

进行测试,我们将非常感激

由于

13 个答案:

答案 0 :(得分:95)

jQuery在某些情况下使用正则表达式来删除脚本标记,我很确定它的开发人员有这么好的理由。可能某些浏览器在使用innerHTML插入时执行脚本。

这是正则表达式:

/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi

在人们开始哭泣之前“但HTML的正则表达是邪恶的”:Yes, they are - 但对于脚本标签,由于特殊行为,它们是安全的 - <script>部分可能不包含</script>除非它应该在这个位置结束。因此很容易将它与正则表达式匹配。但是,从快速查看,上面的正则表达式不会考虑结束标记内的尾随空格,因此您必须测试</script   等是否仍然有用。

答案 1 :(得分:81)

尝试使用正则表达式删除HTML标记是有问题的。你不知道脚本或属性值是什么。一种方法是将其作为div的innerHTML插入,删除任何脚本元素并返回innerHTML,例如。

  function stripScripts(s) {
    var div = document.createElement('div');
    div.innerHTML = s;
    var scripts = div.getElementsByTagName('script');
    var i = scripts.length;
    while (i--) {
      scripts[i].parentNode.removeChild(scripts[i]);
    }
    return div.innerHTML;
  }

alert(
 stripScripts('<span><script type="text/javascript">alert(\'foo\');<\/script><\/span>')
);

请注意,目前,如果使用innerHTML属性插入,浏览器将不会执行脚本,并且可能永远不会,因为元素未添加到文档中。

答案 2 :(得分:42)

正则表达式是可以打败的,但是如果你有一个HTML的字符串版本,你不想注入DOM,它们可能是最好的方法。你可能想把它放在循环中来处理类似的东西:

<scr<script>Ha!</script>ipt> alert(document.cookie);</script>

这就是我所做的,使用上面的jquery正则表达式:

var SCRIPT_REGEX = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi;
while (SCRIPT_REGEX.test(text)) {
    text = text.replace(SCRIPT_REGEX, "");
}

答案 3 :(得分:11)

这个正则表达式也应该起作用:

<script(?:(?!\/\/)(?!\/\*)[^'"]|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\/\/.*(?:\n)|\/\*(?:(?:.|\s))*?\*\/)*?<\/script>

它甚至允许在其中包含“有问题”的变量字符串:

<script type="text/javascript">
   var test1 = "</script>";
   var test2 = '\'</script>';
   var test1 = "\"</script>";
   var test1 = "<script>\"";
   var test2 = '<scr\'ipt>';
   /* </script> */
   // </script>
   /* ' */
   // var foo=" '
</script>

接下来jQuery和Prototype在这些上失败了......

编辑17年7月31日:添加了a)非捕获组以获得更好的性能(并且没有空组)和b)支持JavaScript注释。

答案 4 :(得分:10)

每当您必须使用基于Regex的脚本标记清理时。至少以

的形式向结束标记添加空格
</script\s*>

其他类似的事情

<script>alert(666)</script   >

将保留,因为在标记名有效后尾随空格。

答案 5 :(得分:4)

为什么不使用jQuery.parseHTML()http://api.jquery.com/jquery.parsehtml/

答案 6 :(得分:1)

在我的情况下,我需要一个要求来解析页面标题AND并拥有jQuery的所有其他优点,减去它触发脚本。这是我的解决方案似乎有效。

        $.get('/somepage.htm', function (data) {
            // excluded code to extract title for simplicity
            var bodySI = data.indexOf('<body>') + '<body>'.length,
                bodyEI = data.indexOf('</body>'),
                body = data.substr(bodySI, bodyEI - bodySI),
                $body;

            body = body.replace(/<script[^>]*>/gi, ' <!-- ');
            body = body.replace(/<\/script>/gi, ' --> ');

            //console.log(body);

            $body = $('<div>').html(body);
            console.log($body.html());
        });

这种快捷方式担心脚本,因为您不是要删除脚本标记和内容,而是使用注释呈现方案替换它们以使它们无用,因为您将使用注释来分隔脚本声明。

如果这仍然存在问题,请告诉我,因为它也会对我有所帮助。

答案 7 :(得分:1)

如果要从某些HTML文本中删除所有JavaScript代码,则删除<script>标记是不够的,因为JavaScript仍然可以存在于“onclick”,“onerror”,“href”和其他属性中。

试试这个处理所有这些的npm模块: https://www.npmjs.com/package/strip-js

答案 8 :(得分:0)

以下是各种shell脚本,可用于删除不同的元素。

# doctype
find . -regex ".*\.\(html\|py\)$" -type f -exec sed -i "s/<\!DOCTYPE\s\+html[^>]*>/<\!DOCTYPE html>/gi" {} \;

# meta charset
find . -regex ".*\.\(html\|py\)$" -type f -exec sed -i "s/<meta[^>]*content=[\"'][^\"']*utf-8[\"'][^>]*>/<meta charset=\"utf-8\">/gi" {} \;

# script text/javascript
find . -regex ".*\.\(html\|py\)$" -type f -exec sed -i "s/\(<script[^>]*\)\(\stype=[\"']text\/javascript[\"']\)\(\s\?[^>]*>\)/\1\3/gi" {} \;

# style text/css
find . -regex ".*\.\(html\|py\)$" -type f -exec sed -i "s/\(<style[^>]*\)\(\stype=[\"']text\/css[\"']\)\(\s\?[^>]*>\)/\1\3/gi" {} \;

# html xmlns
find . -regex ".*\.\(html\|py\)$" -type f -exec sed -i "s/\(<html[^>]*\)\(\sxmlns=[\"'][^\"']*[\"']\)\(\s\?[^>]*>\)/\1\3/gi" {} \;

# html xml:lang
find . -regex ".*\.\(html\|py\)$" -type f -exec sed -i "s/\(<html[^>]*\)\(\sxml:lang=[\"'][^\"']*[\"']\)\(\s\?[^>]*>\)/\1\3/gi" {} \;

答案 9 :(得分:0)

/(?:?!(小于/秒\ w)的百分比抑制率数据^&LT;] &LT; /秒\ W * / GI; - 使用

删除任何组合中的任何序列

答案 10 :(得分:0)

你可以尝试

$("your_div_id").remove();  

 $("your_div_id").html(""); 

答案 11 :(得分:0)

试试这个:

var text = text.replace(/<script[^>]*>(?:(?!<\/script>)[^])*<\/script>/g, "")

答案 12 :(得分:0)

您可以不使用正则表达式来执行此操作。只需使用document.createElement()将HTML字符串转换为HTML节点,然后使用element.getElementsByTagName('script')查找所有脚本,然后只需remove()即可!

有趣的事实:创建带有<script>标签的元素时,SO的演示不喜欢它!下面的代码段不会运行,但可以在Full Working Demo at JSBin.com上使用。

var el = document.createElement( 'html' );
el.innerHTML = "<p>Valid paragraph.</p><p>Another valid paragraph.</p><script>Dangerous scripting!!!</script><p>Last final paragraph.</p>";

var scripts = el.getElementsByTagName( 'script' ); // Live NodeList of your anchor elements

for(var i = 0; i < scripts.length; i++) {
  var script = scripts[i];
  script.remove();
}

console.log(el.innerHTML);

这是比正则表达式更干净的解决方案,恕我直言。