Php 向标记中的每个表添加类名

Php 向标记中的每个表添加类名,php,regex,Php,Regex,在PHP中,我需要搜索$post内容并找到所有开头的标记,以便根据其索引添加唯一的类名。我知道下面的代码是错误的,但希望能让大家明白这一点 $content = '<table></table><p></p><table></table><p></p><table></table><p></p>'; preg_match_all('/find all &

在PHP中,我需要搜索$post内容并找到所有开头的
标记,以便根据其索引添加唯一的类名。我知道下面的代码是错误的,但希望能让大家明白这一点

$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);
}
$content='';
preg_match_all(“/find all tags/”,$content,$matches);
对于($i=0;$i
我个人会在没有正则表达式的情况下做这件事

$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++;
}
$content='';
函数str_replace_count($search,$replace,$subject,$count){
返回内爆($replace,explode($search,$subject,$count+1));
}
$i=1;
while(strpos($content,,)!==FALSE){
$content=str_replace_计数(“”,,$content,1);
$i++;
}
演示


请记住,HTML标记类值不能以数字开头。

如果没有正则表达式,我个人会这样做

$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++;
}
$content='';
函数str_replace_count($search,$replace,$subject,$count){
返回内爆($replace,explode($search,$subject,$count+1));
}
$i=1;
while(strpos($content,,)!==FALSE){
$content=str_replace_计数(“”,,$content,1);
$i++;
}
演示


请记住,HTML标记类值不能以数字开头。

更好的方法是使用DOM解析器。使用正则表达式,您可以轻松完成此简单任务,但为了正确的工具,请使用解析器:

$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;
回显preg_replace_回调(“~~”,函数()使用(&$counter){
返回“class=”table.'$counter++.“>”;
}(单位:$content);

更好的方法是使用DOM解析器。使用正则表达式,您可以轻松完成此简单任务,但为了正确的工具,请使用解析器:

$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;
回显preg_replace_回调(“~~”,函数()使用(&$counter){
返回“class=”table.'$counter++.“>”;
}(单位:$content);

如果使用
str.replace()
,它将一直替换到不匹配为止,因此它将与
匹配并全部替换,第二个循环将找不到任何匹配项

这个答案有一个变通方法,因此,您的代码应该如下所示:

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; 
函数str\u replace\u first($from,$to,$content)
{
$from='/'.preg_quote($from'/')。'/';
返回preg_replace($from,$to,$content,1);
}
$content='

'; preg_match_all('/',$content,$matches); $result=$content; foreach($将[0]匹配为$key=>$value){ $new_值=''; $result=str_replace_first($value,$new_value,$result); } 回声$结果;
演示

如果使用
str.replace()
,它将一直替换到不匹配为止,因此它将与
匹配并全部替换,第二个循环将找不到任何匹配

这个答案有一个变通方法,因此,您的代码应该如下所示:

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; 
函数str\u replace\u first($from,$to,$content)
{
$from='/'.preg_quote($from'/')。'/';
返回preg_replace($from,$to,$content,1);
}
$content='

'; preg_match_all('/',$content,$matches); $result=$content; foreach($将[0]匹配为$key=>$value){ $new_值=''; $result=str_replace_first($value,$new_value,$result); } 回声$结果;

Demo

如果保留最后一个参数1,则抛出一个错误,致命错误:只能通过引用传递变量。如果删除变量或使用$count,则会将相同的类名添加到任何表“c_1”中。不知道如何解决这个问题是的,现在我看到了我的错误。我已经更新了答案并对其进行了测试。现在它正在工作。如果我保留最后一个参数1,则会引发错误,致命错误:只有变量可以通过引用传递。如果删除变量或使用$count,则会将相同的类名添加到任何表“c_1”中。不知道如何解决这个问题是的,现在我看到了我的错误。我已经更新了答案并进行了测试。现在它开始工作了。我使用了正则表达式解决方案。我发现DOM解决方案确实可以将类添加到我的表中,但也出现了另一个问题,即我的html实体丢失了编码。我的标记中有许多奇怪的字符,比如学位符号,°。Regex看起来更短,也更方便,可以获得相同的结果,但更好地处理dom。可以考虑HTML输入的编码。我在这里做了一个现场演示,谢谢Revo…它解决了编码问题。mb_convert_编码($content,'HTML-ENTITIES,'UTF-8')我使用了Regex解决方案。我发现DOM解决方案确实可以将类添加到我的表中,但也出现了另一个问题,即我的html实体丢失了编码。我的标记中有许多奇怪的字符,比如学位符号,°。Regex看起来更短,也更方便,可以获得相同的结果,但更好地处理dom。可以考虑HTML输入的编码。我在这里做了一个现场演示,谢谢Revo…它解决了编码问题。mb_转换_编码($content,'HTML-ENTITIES','UTF-8')