使用背景颜色匹配所有元素

时间:2016-07-15 14:56:36

标签: php html regex pattern-matching domdocument

这就是问题 - 在TinyMCE中,我正在使用它在span包装器而不是父元素上添加background-color。我正在尝试搜索内容字符串并抓取span样式以将其放在父元素上。我有这样的HTML:

<h3><span style="background-color: #000000;">Hello World!</span></h3>

因此,我尝试将spanbackgroundbackground-color匹配,并将其作为style添加到其父级。我正在尝试使用DOMDocument,但我不太熟悉它:

$html       = '<h3><span style="background-color: #000000;">Hello World!</span></h3>';
$htmlDOM    = new DOMDocument();
$htmlDOM->loadHTML( $html );
$xpath      = new DOMXPath( $htmlDOM );
$headers = $xpath->query( '//h1//span|//h2//span|//h3//span|//h4//span|//h5//span|//h6//span' );

foreach( $headers as $index => $element ) {
    print_r( $element );    // The Header Element

    if( $element->attributes->length ) {
        foreach( $element->attributes as $asdf => $attr ) {
            print_r( $attr );   // The Span Attributes ( style )
        }
    }
}

我得到了上面的实际样式属性,但我不知道如何将它分配给父级。我不确定这是否比preg_match()快,但我对正则表达式不够熟悉。任何帮助/建议或提示将不胜感激!

3 个答案:

答案 0 :(得分:2)

$html       = '<h3><span style="background-color: #000000;">Hello World!</span></h3>';
$htmlDOM    = new DOMDocument();
$htmlDOM->loadHTML( $html );
$xpath      = new DOMXPath( $htmlDOM );
// Find `h*` having child `span` with `style` attribute    
$headers = $xpath->query( '//*[contains("h1|h2|h3|h4|h5|h6", name())  and span[@style]]');

foreach( $headers as $element) {
    // Find `span` element
    $span = $xpath->query('./span', $element)->item(0);
    // Move all attributes from `span` to `h*
    foreach($span->attributes as $attr)
       $element->setAttribute($attr->name, $attr->nodeValue);
    // Save value of `span`
    $value = $element->nodeValue;
    // Remove `span` 
    $span->parentNode->removeChild($span);
    // Set former `span` value as `h*` value
    $element->nodeValue = $value;
}

echo $htmlDOM->saveHTML();

<强> demo

答案 1 :(得分:0)

dom解决方案会更好。但是如果你想使用正则表达式解决方案,你可以使用:

$html     = '<h3><span style="background-color: #000000;">Hello World!</span></h3>';
$html_new = preg_replace("@(<h\d[^>]*)(>)(\s*<span[^<>]+)(style\s*=\s*["'][^"']*["'])[^>]*>([^<>]+)</span>@", "$1 $4$2$5", $html);

它仅适用于h1等元素,如果span元素将直接跟随并且没有子元素。

答案 2 :(得分:0)

感谢/ u / splash58的答案,它让我朝着正确的方向前进:

$html       = '<h3><span style="background-color: #000000;">Hello World!</span></h3>';
$htmlDOM    = new DOMDocument();
$htmlDOM->loadHTML( $html );
$xpath      = new DOMXPath( $htmlDOM );
$elements   = $xpath->query( '//h1//span|//h2//span|//h3//span|//h4//span|//h5//span|//h6//span' );

if( $elements->length ) {
    foreach( $elements as $span ) {
        $span_style = $span->getAttribute( 'style' );

        if( false !== strpos( $span_style, 'background' ) ) {
            $parent_style   = $span->parentNode->getAttribute( 'style' );
            $parent_style   = rtrim( $parent_style, ';' );
            $span_style     = rtrim( $span_style, ';' );

            $new_style      = "{$parent_style}; {$span_style};";
            $parent_style   = $span->parentNode->setAttribute( 'style', $new_style );
            $span->parentNode->nodeValue = $span->nodeValue;
        }
    }
}

echo $htmlDOM->saveHTML();

我不确定的一件事是为什么在我没有专门删除它时删除了跨度。这似乎发生在我将跨度nodeValue分配给父级之后。如果有人知道为什么会这样或澄清,请在下面评论并告诉我!