In PHP I need to search through my $post content and find all the opening <table>
tags to add a unique class name based on its index. I know the code below is wrong but hopefully gets the point across.
$content = '<table></table><p></p><table></table><p></p><table></table><p></p>';
preg_match_all('/find all <table> tags/', $content, $matches);
for ($i=0; $i < count($matches); $i++) {
$new_value = '<table class=""' . $i . ' >';
str_replace( $matches[$i], $new_value, $content);
}
The better way is using a DOM parser. With Regular Expressions you are able to do this simple task without a mess but for right tool's sake, do it with a parser:
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
libxml_use_internal_errors(false);
$tables = $dom->getElementsByTagName('table');
foreach ($tables as $i => $table) {
$table->setAttribute('class', "table_$i");
}
echo $dom->saveHTML();
$counter = 0;
echo preg_replace_callback('~<table\K>~', function() use (&$counter) {
return ' class="table_' . $counter++ . '">';
}, $content);
I would personally do it without regex.
$content = '<table></table><p></p><table></table><p></p><table></table><p></p>';
function str_replace_count($search, $replace, $subject, $count) {
return implode($replace, explode($search, $subject, $count + 1));
}
$i = 1;
while (strpos($content, '<table>') !== FALSE) {
$content = str_replace_count('<table>', '<table class="c_' . $i . '">', $content, 1);
$i++;
}
Demo http://sandbox.onlinephpfunctions.com/
Remember that HTML tags class values cannot start with a number.
You use str.replace()
and it will replace till no match so it will match against <table>
and replace them all , the second loop will not find any match .
There is a workaround from this answer Using str_replace so that it only acts on the first match? so , your code should look like this :
function str_replace_first($from, $to, $content)
{
$from = '/'.preg_quote($from, '/').'/';
return preg_replace($from, $to, $content, 1);
}
$content = '<table></table><p></p><table></table><p></p><table></table><p></p>';
preg_match_all('/<table>/', $content, $matches);
$result=$content;
foreach ($matches[0] As $key => $value) {
$new_value = '<table class=' . $key . ' >';
$result=str_replace_first($value, $new_value,$result);
}
echo $result;