如何删除脚本元素中的CDATA块?

时间:2017-05-03 12:38:43

标签: php regex xpath preg-replace cdata

使用PHP,在HTML文件中,我想删除脚本元素中的CDATA块。

<script type="text/javascript">
    /* <![CDATA[ */
    var A=new Array();
    ..........................
    ..........................
/* ]]> */
</script>
some text2 ........................
some text3 ........................
some text4 ........................
<script type="text/javascript">
    /* <![CDATA[ */
    var B=new Array();
    ..........................
    ..........................
/* ]]> */
some text5 ........................

我还没有找到如何选择&amp;使用XPath&amp;删除此节点PHP DomDocument

我试过这个正则表达式 $re = '/\/\*\s*<!\[CDATA\[[\s\S]*\/\*\s*\]\]>\s*\*\//i';

但这会删除所有文本,包括2个CDATA块之间的文本。

结果我得到一个空字符串而不是

some text2 ........................ 
some text3 ........................ 
some text4 ........................ 
some text5 ........................

有什么想法吗?

使用ThW解决方案进行更新:

使用此页面,似乎CDATA部分的文本没有很好地解析

libxml_use_internal_errors(true);
$domDoc = new DOMDocument();
$domDoc->loadHTMLFile('https://www.maisons-qualite.com/le-reseau-mdq/recherche-constructeurs-agrees/construction-maison-neuve-centre-val-loire');
libxml_clear_errors();

$xpath = new DOMXpath($domDoc);
foreach($xpath->evaluate('//text()') as $section) {
  if ($section instanceof DOMCDATASection) {
    print_r($section->textContent);
    $section->parentNode->removeChild($section);
  }
}
$content = $domDoc->saveHTML();

我收到了这个textContent

.....
.....
function updateConstructeurs(list) {
    for (var i in list) {
        if(list[i]['thumbnail']) {
            jQuery('#reseau-constructeurs').append('<div class="reseau-constructeur">' +
                '<div class="img" style="background-image:url(' + list[i]['thumbnail'] + ')">

代表

function updateConstructeurs(list) {
    for (var i in list) {
        if(list[i]['thumbnail']) {
            jQuery('#reseau-constructeurs').append('<div class="reseau-constructeur">' +
                '<div class="img" style="background-image:url(' + list[i]['thumbnail'] + ')"></div>' +
                '<h3>' + list[i]['title'] + '</h3>' +
                '<a class="btn purple" href="' + list[i]['link'] + '">Accéder à la fiche</a>' +
            '</div>');
        }
    }
}

结果,我们得到了:

,而不是获得一个空字符串
                        '<h3>' + list[i]['title'] + '</h3>' +
                        '<a class="btn purple" href="'%20+%20list%5Bi%5D%5B'link'%5D%20+%20'">Acc&eacute;der &agrave; la fiche</a>' +
                    '</div>');
                }
            }
        }
    /* ]]&gt; */

3 个答案:

答案 0 :(得分:1)

[\s\S]*非贪婪,即[\s\S]*?

\/\*\s*<!\[CDATA\[[\s\S]*?\/\*\s*\]\]>\s*\*\/

演示:https://regex101.com/r/AutLW9/1

答案 1 :(得分:0)

PHP中的Dmitry Egorov解决方案。

$re = '/\/\*\s*<!\[CDATA\[[\s\S]*?\/\*\s*\]\]>\s*\*\//';
$str = '<script type="text/javascript">
    /* <![CDATA[ */
    var A=new Array();
    ..........................
    ..........................
/* ]]> */
</script>
some text2 ........................
some text3 ........................
some text4 ........................
<script type="text/javascript">
    /* <![CDATA[ */
    var B=new Array();
    ..........................
    ..........................
/* ]]> */
</script>
some text5 ........................';
$subst = '';

$result = preg_replace($re, $subst, $str);

echo "The result of the substitution is ".$result;

答案 2 :(得分:0)

CData部分是一种字符节点,如文本节点。在大多数情况下,您以相同的方式处理它们 - 不同之处在于序列化。因此,如果它们是CDATA部分(而不是文本节点),则使用Xpath获取节点并删除它们:

$document = new DOMDocument();
$document->loadHtml($html);
$xpath = new DOMXpath($document);

foreach($xpath->evaluate('//text()') as $section) {
  if ($section instanceof DOMCDATASection) {
    $section->parentNode->removeChild($section);
  }
}

echo $document->saveHtml();

但是你可能想重新考虑一下。没有CDATA部分真的很重要吗?您可能希望删除script元素的内容。这甚至更短:

$document = new DOMDocument();
$document->loadHtml($html);
$xpath = new DOMXpath($document);

foreach($xpath->evaluate('//script/node()') as $node) {
  $node->parentNode->removeChild($section);
}

echo $document->saveHtml();

//script/node()匹配script元素内的任何子节点。无论是CDATA部分,文本节点还是其他任何内容。