我目前正在撰写一个获取Facebook和Twitter提要的课程,然后将它们组合成一个用于在网站上显示的课程。
但是由于a
个元素在一个简单的substr
函数后最终没有被关闭,我遇到一个限制输入文本输出的问题。
想象一下我有这个字符串:
'Check out our site at <a href="http://site.com/">site.com</a>'
我想将此限制为50个字符。如果我只是做substr($input,0,50)
,我将会得到以下内容:
'Check out our site at <a href="http://site.com/">s'
一个未关闭的a
元素,它会将我网站的其余部分转换为链接。
我想可能正在使用DOMDocument我可以暂时用<a></a>
之间的部分替换完整的URL,进行减法,然后重新应用链接。
然而我无法弄清楚如何做到这一点,它给我留下了另一个问题/选择:如果 - 假设我能够暂时替换链接 - 在减法后我最终得到了一半的链接:
'Check out our site at sit'
然后很难重新应用链接,所以最好用[[id]]
替换它,并让脚本记住文本的长度。
无论如何,有没有人可以帮我解决这个问题?
编辑它仅适用于a
个标签,因为我strip_tags
就是其他所有标签。
答案 0 :(得分:1)
php.net/substr的这段代码非常适用于此。
示例:
echo substrws("Check out our site at <a href=\"http://site.com/\">site.com</a>. It's really <strong>nice</strong>", 50);
收率:
Check out our site at <a href="http://site.com/">site.com</a>.
代码:
/**
* word-sensitive substring function with html tags awareness
* @param text The text to cut
* @param len The maximum length of the cut string
* @returns string
**/
function substrws( $text, $len=180 ) {
if( (strlen($text) > $len) ) {
$whitespaceposition = strpos($text," ",$len)-1;
if( $whitespaceposition > 0 )
$text = substr($text, 0, ($whitespaceposition+1));
// close unclosed html tags
if( preg_match_all("|<([a-zA-Z]+)>|",$text,$aBuffer) ) {
if( !empty($aBuffer[1]) ) {
preg_match_all("|</([a-zA-Z]+)>|",$text,$aBuffer2);
if( count($aBuffer[1]) != count($aBuffer2[1]) ) {
foreach( $aBuffer[1] as $index => $tag ) {
if( empty($aBuffer2[1][$index]) || $aBuffer2[1][$index] != $tag)
$text .= '</'.$tag.'>';
}
}
}
}
}
return $text;
}
答案 1 :(得分:0)
另一个解决方案是strip_tags() - php的功能如下:
<?php
$text = '<p>Check out our site at </p><!-- other html stuff anywhere--> <a href="http://site.com/">site.com</a>';
echo strip_tags($text);
echo "\n";
// juts allow <p> and <a>
echo strip_tags($text, '<p><a>');
?>
答案 2 :(得分:0)
我最后编写了自己的函数,也许可以使用一些改进,但它有效:
private function substr_html($input,$limit){
$original = $input;
if(strlen($input) <= $limit)
return $input;
$pattern = '#<a\s+.*?href=[\'"]([^\'"]+)[\'"]\s*?.*?>((?:(?!</a>).)*)</a>#i';
// Match all 'a' elements
preg_match_all($pattern,$input,$matches);
// If no links were found, perform a simple substr()
if(count($matches[0]) == 0)
return substr($input,0,$limit).'...';
$uni = sha1(uniqid());
preg_replace($pattern,$uni,$input);
$input = explode($uni,$input);
$tmp = $output = '';
// Go through the splitted input
foreach($input as $i){
if(strlen($tmp.$i) < $limit){
// If we can fit the next text value without reaching the limit, do it
$tmp .= $i;
$output .= $i;
}else{
// Add whatever we can fit from the last text value and break the loop
$diff = abs($limit - strlen($tmp));
$output .= substr($i,0,$diff);
break;
}
if(strlen($tmp) < $limit){ // Do we still have room before we reach the limit?
$nextlink = array_shift($matches[1]);
$nexttext = array_shift($matches[2]);
if(strip_tags($nexttext,$this->allowed_tags) != '')
if(strlen($tmp.$nexttext) < $limit){
// Add the next link if it fits
$tmp .= $nexttext;
$output .= '<a href="'.$nextlink.'" target="_blank">'.$nexttext.'</a>';
}else{
// Add whatever we can fit from the last link and break the loop
$diff = abs($limit - strlen($tmp));
$output .= '<a href="'.$nextlink.'" target="_blank">'.substr($nexttext,0,$diff).'</a>';
break;
}
}
}
// Trim string and remove linebreaks
$output = trim(preg_replace('/((<br>|<br\/>|<br \/>){1,})/'," ",$output));
return $output.(strip_tags($original) != strip_tags($output) ? '...' : '');
}