0

I'm trying to match the class attribute of <html> tag and to add a class name using preg_replace().
Here is what I tried so far:

$content = '<!DOCTYPE html><html lang="en" class="dummy"><head></head><body></body></html>';
$pattern = '/< *html[^>]*class *= *["\']?([^"\']*)/i';
if(preg_match($pattern, $content, $matches)){
    $content = preg_replace($pattern, '<html class="$1 my-custom-class">', $content);
}
echo htmlentities($content);

But, I got only this returned:

<!DOCTYPE html><html class="dummy my-custom-class">"><head></head><body></body></html>

The attribute lang="en" is dropped out and the tag is appended with the duplicates like ">">. Please help me.

Sithu
  • 4,752
  • 9
  • 64
  • 110

2 Answers2

1

Remove the * in pattern for regex way

Use this pattern

/<html[^>]*class *= *["\']?([^"\']*)/i

I suggest use Dom parser for parsing the html

<?php
libxml_use_internal_errors(true);
$html="<!DOCTYPE html><html lang='en' class='dummy'><head></head><body></body></html>";

$dom = new DOMDocument;
$dom->loadHTML($html);


foreach ($dom->getElementsByTagName('html') as $node) {

    $node->setAttribute('class','dummy my-custom-class');

}

$html=$dom->saveHTML();
echo $html;

OUTPUT:

<!DOCTYPE html>
<html lang="en" class="dummy my-custom-class"><head></head><body></body></html>
Nambi
  • 11,944
  • 3
  • 37
  • 49
  • Thanks for your answer, but removing the `*` is not working as expected. And regarding with `DomDocument`, I got these errors `Warning: domdocument::domdocument() expects at least 1 parameter, 0 given` and `Fatal error: Call to undefined method domdocument::loadHTML()`. I don't want to use `DomDocument`because it needs additional server requirements and my code will be run on every page load as it is invoked in the output buffering handler. `DomDocument` needs `php_domxml.dll` disabled on the server. – Sithu Apr 08 '14 at 04:54
  • The purpose is to add a respective class name for each IE version to the `` tag from the output handler. – Sithu Apr 08 '14 at 04:56
  • @Sithu just add the **libxml_use_internal_errors(true);** to disable the internal errors. – Nambi Apr 08 '14 at 05:06
1

Please try this code it works, perfectly well :)

<?php

$content = '<!DOCTYPE html><html lang="en" class="dummy"><head></head><body></body></html>';
$pattern = '/(<html.*class="([^"]+)"[^>]*>)/i';

$callback_fn = 'process';

$content=preg_replace_callback($pattern, $callback_fn, $content);


function process($matches) {

$matches[1]=str_replace($matches[2],$matches[2]." @ My Own Class", $matches[1]);

return $matches[1];

}


echo htmlentities($content);

?>
  • Great! It did work, but it has a glitch. It is not working when the class name is space like `class=" "`. This is my code fix `function process($matches) { $find = 'class="'.$matches[2].'"'; $replace = 'class="'.$matches[2].' my-class-name"'; $matches[1] = str_replace($find, $replace, $matches[1]); return $matches[1]; }` – Sithu Apr 08 '14 at 06:54