![](/img/trans.png)
[英]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.