Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果模式不在另一个模式之后,则正则表达式匹配-PHP_Php_Regex_Negative Lookahead - Fatal编程技术网

如果模式不在另一个模式之后,则正则表达式匹配-PHP

如果模式不在另一个模式之后,则正则表达式匹配-PHP,php,regex,negative-lookahead,Php,Regex,Negative Lookahead,我想将iframe对象包装在div类中,但前提是它尚未包装在该div类中。我正在尝试对该div类使用负匹配模式,以便preg_replace不会匹配并返回原始的$content。但它仍然匹配: <?php $content = <<< EOL <div class="aoa_wrap"><iframe width="500" height="281" src="https://www.youtube.com/embed/uuZE_IRwLNI" fram

我想将iframe对象包装在div类中,但前提是它尚未包装在该div类中。我正在尝试对该div类使用负匹配模式,以便preg_replace不会匹配并返回原始的$content。但它仍然匹配:

<?php
$content = <<< EOL
<div class="aoa_wrap"><iframe width="500" height="281" src="https://www.youtube.com/embed/uuZE_IRwLNI" frameborder="0" allowfullscreen></iframe></div>
EOL;
$pattern = "~(?!<div(.*?)aoa_wrap(.*?)>)<iframe\b[^>]*>(?:(.*?)?</iframe>)?~";
$replace = '<div class="aoa_wrap">${0}</div>';
$content = preg_replace( $pattern, $replace, $content);
echo $content . "\n";
?>

输出(不正确):



我不确定为什么一开始的否定模式不会导致preg_replace按预期返回原始的$content。我是否遗漏了一些明显的东西?

我最终尝试了上面评论中建议的DOM。这对我来说很有用:

<?php

$content = <<< EOL
<p>something here</p>
<iframe width="500" height="281" src="https://www.youtube.com/embed/uuZE_IRwLNI" frameborder="0" allowfullscreen></iframe>
<p><img src="test.jpg" /></p>
EOL;

$doc = new DOMDocument();
$doc->loadHTML( "<div>" . $content . "</div>" );


// remove <!DOCTYPE  and html and body tags that loadHTML adds:

$container = $doc->getElementsByTagName('div')->item(0);
$container = $container->parentNode->removeChild($container);
while ($doc->firstChild) {
    $doc->removeChild($doc->firstChild);
}
while ($container->firstChild ) {
    $doc->appendChild($container->firstChild);
}


// get all iframes and see if we need to wrap them in our aoa_wrap class:

$nodes = $doc->getElementsByTagName( 'iframe' );

foreach ( $nodes as $node ) {

        $parent = $node->parentNode;
        // skip if already wrapped in div class 'aoa_wrap'
        if ( isset( $parent->tagName ) && 'div' == $parent->tagName && 'aoa_wrap' == $parent->getAttribute( 'class' ) ) { 
                continue;
        }

        // create new element for class "aoa_wrap"
        $wrap = $doc->createElement( "div" );
        $wrap->setAttribute( "class", "aoa_wrap" );

        // clone the iframe node as child
        $wrap->appendChild( $node->cloneNode( true ) );

        // replace original iframe node with new div class wrapper node
        $parent->replaceChild( $wrap, $node );

}

echo $doc->saveHTML();

?>

我最终尝试了上面评论中建议的DOM。这对我来说很有用:

<?php

$content = <<< EOL
<p>something here</p>
<iframe width="500" height="281" src="https://www.youtube.com/embed/uuZE_IRwLNI" frameborder="0" allowfullscreen></iframe>
<p><img src="test.jpg" /></p>
EOL;

$doc = new DOMDocument();
$doc->loadHTML( "<div>" . $content . "</div>" );


// remove <!DOCTYPE  and html and body tags that loadHTML adds:

$container = $doc->getElementsByTagName('div')->item(0);
$container = $container->parentNode->removeChild($container);
while ($doc->firstChild) {
    $doc->removeChild($doc->firstChild);
}
while ($container->firstChild ) {
    $doc->appendChild($container->firstChild);
}


// get all iframes and see if we need to wrap them in our aoa_wrap class:

$nodes = $doc->getElementsByTagName( 'iframe' );

foreach ( $nodes as $node ) {

        $parent = $node->parentNode;
        // skip if already wrapped in div class 'aoa_wrap'
        if ( isset( $parent->tagName ) && 'div' == $parent->tagName && 'aoa_wrap' == $parent->getAttribute( 'class' ) ) { 
                continue;
        }

        // create new element for class "aoa_wrap"
        $wrap = $doc->createElement( "div" );
        $wrap->setAttribute( "class", "aoa_wrap" );

        // clone the iframe node as child
        $wrap->appendChild( $node->cloneNode( true ) );

        // replace original iframe node with new div class wrapper node
        $parent->replaceChild( $wrap, $node );

}

echo $doc->saveHTML();

?>


您不应该为此使用正则表达式。使用DOM和xpath。您考虑的是消极的向后看,而不是向前看。但这是行不通的,因为lookbehinds不能包含量词。前面的评论是对的,如果你使用像这样的专用工具,这将容易得多。你不应该为此使用正则表达式。使用DOM和xpath。您考虑的是消极的向后看,而不是向前看。但这是行不通的,因为lookbehinds不能包含量词。前面的评论是对的,如果你使用像这样的专用工具,这将容易得多。