[英]regular expression to remove all tags with content and html code from a string
[英]Removing all script tags from html with JS Regular Expression
我想从 Pastebin 的这个 HTML 中去除脚本标签:
我尝试使用以下正则表达式:
html.replace(/<script.*>.*<\/script>/ims, " ")
但它不会删除 HTML 中的所有脚本标签。它只会删除内联脚本。 我正在寻找一些可以删除所有脚本标签(内联和多行)的正则表达式。 如果对我的样品http://pastebin.com/mdxygM0a进行测试,我们将不胜感激
jQuery 在某些情况下使用正则表达式来删除脚本标签,我很确定它的开发人员有充分的理由这样做。 可能某些浏览器在使用innerHTML
插入脚本时会执行脚本。
这是正则表达式:
/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi
在人们开始哭泣“但是 HTML 的正则表达式是邪恶的”之前: 是的,它们是- 但是对于脚本标签,由于特殊行为它们是安全的 - <script>
部分可能根本不包含</script>
除非它应该结束在这个 position。 因此,很容易将其与正则表达式匹配。 但是,快速浏览一下,上面的正则表达式不考虑结束标记内的尾随空格,因此您必须测试</script
等是否仍然有效。
尝试使用正则表达式删除 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 属性插入,浏览器将不会执行脚本,并且可能永远不会执行,尤其是当元素未添加到文档中时。
正则表达式是可击败的,但如果您有一个不想注入 DOM 的 HTML 的字符串版本,那么它们可能是最好的方法。 你可能想把它放在一个循环中来处理类似的事情:
<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, "");
}
这个正则表达式也应该工作:
<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 在这些上都失败了……
编辑 2017 年 7 月 31 日:添加了 a) 非捕获组以获得更好的性能(并且没有空组)和 b) 支持 JavaScript 评论。
每当您不得不求助于基于正则表达式的脚本标记清理时。 至少以以下形式在结束标记中添加一个空格
</script\s*>
否则像
<script>alert(666)</script >
将保留,因为标记名后的尾随空格有效。
为什么不使用 jQuery.parseHTML() http://api.jquery.com/jquery.parsehtml/ ?
如果你想从一些 HTML 文本中删除所有 JavaScript 代码,那么删除<script>
标记是不够的,因为 JavaScript 仍然可以存在于“onclick”中,“参考错误”,“参考”
试试这个处理所有这些的 npm 模块: https://www.npmjs.com/package/strip-js
在我的情况下,我需要解析页面标题并拥有 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());
});
这种快捷方式担心脚本,因为您没有尝试删除脚本标签和内容,而是将它们替换为注释呈现方案以破坏它们无用,因为您将使用注释分隔脚本声明。
让我知道这是否仍然存在问题,因为它也会帮助我。
您可以在没有正则表达式的情况下执行此操作。 只需使用document.createElement()
将您的 HTML 字符串转换为 HTML 节点,找到所有带有element.getElementsByTagName('script')
,然后remove()
它们!
有趣的事实:当你创建一个带有<script>
标签的元素时,SO 的演示不喜欢它,下面的代码片段不会运行:但它确实适用于: 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);
这是一个比正则表达式更清洁的解决方案,恕我直言。
以下是各种 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" {} \;
/(?:(?!</s\w)<[^<] ) </s\w*/gi; - 删除任意组合的任何序列
尝试这个:
var text = text.replace(/<script[^>]*>(?:(?!<\/script>)[^])*<\/script>/g, "")
考虑以下字符串:
var str = "<script>var false_closing_tag = '</script>';</script>";
var stripped = str.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
console.log(stripped); // Logs: ';</script>
当前投票最多的正则表达式答案将无法完全删除它。 (尝试一下)。 我什至无法在 SO 编辑器或 JSFiddle 中运行它,因为它们在运行代码之前都没有使用足够的方法来解析代码。
另一个涉及将它添加到<div>
元素然后拉动 div 的innerText
的选项也有负面影响:它实际上会运行代码(这是一个安全问题)并且它会删除所有 HTML 而不是只是脚本标签。
解决方案
您需要实际解析文本:
function stripScriptTags(str){
if(typeof str !== 'string') {
return false;
}
var opened_quote_type = null;
var in_script_tag = false;
var string_buffer = [];
for (let i = 0; i < str.length; i++) {
if(opened_quote_type === null && ["'", '"', '`'].includes(str[i])){
opened_quote_type = str[i];
}else if(opened_quote_type === str[i]){
opened_quote_type = null;
}
if(str.length > i+7 && str.toUpperCase().substring(i, i+7) === '<SCRIPT'){
i += 7;
in_script_tag = true;
}
if(in_script_tag &&
opened_quote_type === null &&
str.length > i+9 &&
str.toUpperCase().substring(i, i+9) === '</SCRIPT>'
){
i += 9;
in_script_tag = false;
}
if(!in_script_tag){
string_buffer.push(str[i]);
}
}
return string_buffer.join('');
}
你可以试试
$("your_div_id").remove();
或者
$("your_div_id").html("");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.