Javascript 删除脚本和样式标记中的所有内容

Javascript 删除脚本和样式标记中的所有内容,javascript,php,jquery,html,regex,Javascript,Php,Jquery,Html,Regex,我有一个名为$articleText的变量,它包含html代码。在和html元素中有脚本和样式代码。我想扫描$articleText并删除这些代码。如果我还可以删除实际的html元素,,和,我也会这样做 我想我需要使用正则表达式,但我并不擅长 有人能帮忙吗 我希望我能提供一些代码,但就像我说的,我不擅长正则表达式,所以我没有任何东西可以展示 我不能使用DOM。我需要特别针对这些特定的标记使用正则表达式正则表达式这样做会非常迟钝,因为标记中可能存在标记,以及诸如标记属性之类的混淆结构 我建议在DO

我有一个名为
$articleText
的变量,它包含html代码。在
html元素中有
脚本
样式
代码。我想扫描
$articleText
并删除这些代码。如果我还可以删除实际的html元素
,我也会这样做

我想我需要使用正则表达式,但我并不擅长

有人能帮忙吗

我希望我能提供一些代码,但就像我说的,我不擅长正则表达式,所以我没有任何东西可以展示


我不能使用DOM。我需要特别针对这些特定的标记使用正则表达式正则表达式这样做会非常迟钝,因为标记中可能存在标记,以及诸如标记属性之类的混淆结构

我建议在DOM(PHP或JavaScript)中执行此操作,它可以通过实际解析来识别和删除不需要的标记。

以下是示例数据:

$in = '
<html>
    <head>
        <script type="text/javascript">window.location="somehwere";</script>
        <style>
            .someCSS {border:1px solid black;}
        </style>
    </head>
    <body>
        <p>....</p>
        <div>
            <script type="text/javascript">document.write("bad stuff");</script>
        </div>
        <ul>
            <li><style type="text/css">#moreCSS {font-weight:900;}</style></li>
        </ul>
    </body>
</html>';
还有一个替代(做同样的事情,只是没有函数声明):

诀窍是要保持平衡。getElementsByTagName将为您遍历整个DOM,因此您不必这样做(没有任何一个具有ChildNodes、nextSibling、nextChild之类的内容)

也许最好的解决办法是介于这两个极端例子之间


我忍不住,这可能是我建议的最好版本。它不包括一个incrementor(
$i
)来把事情搞砸,而是从自下而上删除:

$dom = new DOMDocument('1.0','UTF-8');
$dom->loadHTML($in);

removeElementsByTagName($dom,'script');
removeElementsByTagName($dom,'style');

function removeElementsByTagName($dom,$tagName) {
    $list = $dom->getElementsByTagName($tagName);
    while ( $node = $list->item(0) ) {
        $node->parentNode->removeChild($node);
    }
}

var_dump($dom->saveHTML());

删除节点时,它们会在父节点的子列表中上移,因此1变为0,2变为1,以此类推。继续执行此操作(
,而
),直到不再有节点为止()。还将其包装在可重用函数中。

我认为这应该满足您的需要(假设没有嵌套的脚本和样式标记):

preg_replace('/(]*>.+?|]*>.+?)/s',''.$articleText);

对于这类任务,即使是正则表达式也不是一个好工具,对于小的简单任务,它可能会起作用


如果只想删除标记的内部文本,请使用:

preg_replace('/(]*>).*?()/is',“$1$3”,$txt);
请参见演示


如果还想删除标记,则上述代码中的替换字符串将为空,因此不要在HTML上使用正则表达式。PHP提供了一个解析DOM结构的工具,称为DomDocument

<?php
// some HTML for example
$myHtml = '<html><head><script>alert("hi mom!");</script></head><body><style>body { color: red;} </style><h1>This is some content</h1><p>content is awesome</p></body><script src="someFile.js"></script></html>';

// create a new DomDocument object
$doc = new DOMDocument();

// load the HTML into the DomDocument object (this would be your source HTML)
$doc->loadHTML($myHtml);

removeElementsByTagName('script', $doc);
removeElementsByTagName('style', $doc);
removeElementsByTagName('link', $doc);

// output cleaned html
echo $doc->saveHtml();

function removeElementsByTagName($tagName, $document) {
  $nodeList = $document->getElementsByTagName($tagName);
  for ($nodeIdx = $nodeList->length; --$nodeIdx >= 0; ) {
    $node = $nodeList->item($nodeIdx);
    $node->parentNode->removeChild($node);
  }
}

假设这既是为了不让您的设计被随机样式弄乱,也是为了保护您的站点不受用户脚本的影响,那么删除这些标记并不能保证您的安全

考虑以下情况(例如:onmouseover,onclick):

用户脚本测试
甚至更糟

<h1 onclick='function addCSSRule(a,b,c,d){"insertRule"in a?a.insertRule(b+"{"+c+"}",d):"addRule"in a&&a.addRule(b,c,d)}var style=document.createElement("style");style.appendChild(document.createTextNode("")),document.head.appendChild(style),sheet=style.sheet,addCSSRule(sheet,"*","color: #ff0!important");'>Messing with your styles!</h1>
搞乱你的风格!
这样,开始在文档中插入各种内容就相当简单了

最后一个来自DavidWalsh的样式表MOD示例-

唯一的解决办法

。。。就是要使用一个经过验证的专门从事这方面工作的第三方库。我建议。它将消除用户输入的样式、脚本和讨厌的事件属性。

我不能。它必须是只扫描这些标记的正则表达式。脚本或样式中不应存在嵌套标记tag@jkushner对只需遍历DOMDocument并删除与标记名“script”和“style”@zamnuts匹配的DOMNode/DOMELENT对象,听起来很不错。你能提供这个代码来回答吗?@jkushner你能告诉我们为什么它必须是regex吗?@jkushner我已经演示了如何使用DomDocument---不要使用regex!:)第二个参数是关于允许的标记。这正是他想要的…@HamZa完全忘记了这一点,更新了w/a正确的答案。PHP中没有
g
修饰符。匹配时,您有
preg\u match()
,它将只匹配第一次出现的内容。在javascript等其他语言中,可以使用
g
修饰符匹配所有。在php中,只需使用另一个函数
preg\u match\u all()
。现在换一个怎么样?默认情况下,
preg\u replace()
会替换所有内容。您可以添加第四个参数来限制它。对不起,我太习惯于编写javascript正则表达式了。我已经更新了答案。我忘记了一些重要的事情,不要忘记使用不情愿的(不灵活的)量词。将
+
替换为
+?
。总之+1:)似乎有人在否决所有正则表达式的答案,我的哀悼是的,这是一个耻辱,特别是当提问者特别要求正则表达式的答案时。@HamZa-我习惯了。两次扣分对我的声誉没有影响。OP要求正则表达式解决方案,所以我给了他一个。我的回答清楚地表明regex不是正确的工具,所以我认为downvoter甚至是糟糕的读者,或者只是那些愤怒的家伙之一:)当然,我明白了。但如果没有某种理由,“我不能使用DOM”和“我不能使用字母‘e’”一样有效——这是愚蠢的人为限制。当有人问“我该如何使用”时,我的第一个问题是,“你甚至需要使用”吗?很多时候,询问者不知道有更好的东西存在,或者错误地认为很难处理。无聊的。再说一次,否决票可能是不值得的,但我也有一个DV,所以我怀疑有人试图“具有战略意义”。@Chris-我也明白你的意思。当然,OP应该在他/她的帖子中更加具体。讽刺的是,他/她的帖子(到目前为止)没有获得否决票,但我看到这么多人对答案投了否决票。这没有得到最后一个脚本标签。。。只是第一次,这正是我要找的。谢谢请注意,在使用loadHTML()时,这会中断DOMDocument解析,因为Javascript字符串中有HTML标记:
var str='this NOT get remove';
对于那些认为regex不可能与html协调的人来说,这里有一个来自反反对者部门的解决方案
]*>(
preg_replace('/(<script[^>]*>.+?<\/script>|<style[^>]*>.+?<\/style>)/s', '', $articleText);
preg_replace('/(<(script|style)\b[^>]*>).*?(<\/\2>)/is', "$1$3", $txt);
<?php
// some HTML for example
$myHtml = '<html><head><script>alert("hi mom!");</script></head><body><style>body { color: red;} </style><h1>This is some content</h1><p>content is awesome</p></body><script src="someFile.js"></script></html>';

// create a new DomDocument object
$doc = new DOMDocument();

// load the HTML into the DomDocument object (this would be your source HTML)
$doc->loadHTML($myHtml);

removeElementsByTagName('script', $doc);
removeElementsByTagName('style', $doc);
removeElementsByTagName('link', $doc);

// output cleaned html
echo $doc->saveHtml();

function removeElementsByTagName($tagName, $document) {
  $nodeList = $document->getElementsByTagName($tagName);
  for ($nodeIdx = $nodeList->length; --$nodeIdx >= 0; ) {
    $node = $nodeList->item($nodeIdx);
    $node->parentNode->removeChild($node);
  }
}
<h1 onclick="console.log('user made this happen');">User Scripting Test</h1>
<h1 onclick='function addCSSRule(a,b,c,d){"insertRule"in a?a.insertRule(b+"{"+c+"}",d):"addRule"in a&&a.addRule(b,c,d)}var style=document.createElement("style");style.appendChild(document.createTextNode("")),document.head.appendChild(style),sheet=style.sheet,addCSSRule(sheet,"*","color: #ff0!important");'>Messing with your styles!</h1>