我尝试用 DOMDocument 解析这样的字符串:
$html1 = "<script>document.write('<scr'+'ipt>alert(123);</scr'+'ipt>')</script>";
$dom = new DOMDocument('1.0', 'utf-8');
$dom->loadHTML($html1);
$html2 = $dom->saveHTML();
但是
$html2
有绳子
<html><head><script>document.write('\<scr'+'ipt\>alert(123);')</script></head></html>
缺少
</scr'+'ipt>
部分。
我希望在脚本标记之间收到与输入中相同的字符串。
如果您尝试在
DOMDocument
上加载部分 HTML,它会感到困惑,因为它不知道如何解析它,有时它最终会将其解析为 XML。
为了避免这种情况,请始终确保在添加加载文档之前存在最少的 HTML5 文档。
此外,
<script>
标签内的任何内容都不能有任何</
,这些需要在加载之前进行转义。
在您的情况下,满足最低要求,应该是这样的:
$html1 = "<script>document.write('<scr'+'ipt>alert(123);</scr'+'ipt>')</script>";
$html = '<!DOCTYPE html><html lang="en"><head>'. $html1 . '</head><body></body></html>';
//escape the </ sequences as <\/ inside javascripts
if(preg_match_all('/(<script.*?>)(.*?)(<\/script>)/is', $html, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)){
$t = '';
$o = 0;
foreach($matches as $m){
$t .= substr($html, $o, $m[0][1] - $o);
$t .= $m[1][0].preg_replace('|<\/|', '<\/', $m[2][0]).$m[3][0];
$o = $m[3][1] + strlen($m[3][0]);
}
$t .= substr($html, $o);
$html = $t;
}
$dom = new DOMDocument();
$dom->loadHTML($html);
$html2 = $dom->saveHTML();
echo $html2;