preg_replace 版本
此代码逐步执行每个段落,忽略包含图像标签的段落。这$pcount
对于没有图像的每个段落,变量都会递增,但是如果遇到图像,$pcount
被重置为零。一次$pcount
到达将达到两个点时,广告标记将插入到该段落之前。这应该将广告标记留在两个安全段落之间。然后广告标记变量被取消,因此仅插入一则广告。
以下代码仅用于设置,可以进行修改以以不同的方式分割内容,您还可以修改使用的正则表达式 - 以防万一您使用双 BR 或其他内容来分隔段落。
/// set our advert content
$advert = '<marquee>BUY THIS STUFF!!</marquee>' . "\n\n";
/// calculate mid point
$mpoint = floor(strlen($content) / 2);
/// modify back to the start of a paragraph
$mpoint = strripos($content, '<p', -$mpoint);
/// split html so we only work on second half
$first = substr($content, 0, $mpoint);
$second = substr($content, $mpoint);
$pcount = 0;
$regexp = '/<p>.+?<\/p>/si';
其余的是运行替换的大部分代码。可以对其进行修改以插入多个广告,或支持更多涉及的图像检查。
$content = $first . preg_replace_callback($regexp, function($matches){
global $pcount, $advert;
if ( !$advert ) {
$return = $matches[0];
}
else if ( stripos($matches[0], '<img ') !== FALSE ) {
$return = $matches[0];
$pcount = 0;
}
else if ( $pcount === 1 ) {
$return = $advert . $matches[0];
$advert = '';
}
else {
$return = $matches[0];
$pcount++;
}
return $return;
}, $second);
执行此代码后$content
变量将包含增强的 HTML。
5.3 之前的 PHP 版本
由于您选择的测试区域不支持 PHP 5.3,因此不支持匿名函数,因此您需要使用稍微修改且不太简洁的版本;它使用一个命名函数来代替。
另外,为了支持实际上可能不会在后半部分为广告留下空间的内容,我修改了$mpoint
这样从最后算起就已经是80%了。这将产生包括更多内容的效果$second
部分 - 但也意味着您的广告通常会在标记中放置在更高的位置。该代码没有实施任何后备,因为您的问题没有提到失败时应该发生什么。
$advert = '<marquee>BUY THIS STUFF!!</marquee>' . "\n\n";
$mpoint = floor(strlen($content) * 0.8);
$mpoint = strripos($content, '<p', -$mpoint);
$first = substr($content, 0, $mpoint);
$second = substr($content, $mpoint);
$pcount = 0;
$regexp = '/<p>.+?<\/p>/si';
function replacement_callback($matches){
global $pcount, $advert;
if ( !$advert ) {
$return = $matches[0];
}
else if ( stripos($matches[0], '<img ') !== FALSE ) {
$return = $matches[0];
$pcount = 0;
}
else if ( $pcount === 1 ) {
$return = $advert . $matches[0];
$advert = '';
}
else {
$return = $matches[0];
$pcount++;
}
return $return;
}
echo $first . preg_replace_callback($regexp, 'replacement_callback', $second);