缩短文本推文,而不切断链接 [英] Shortening text tweet-like without cutting links inside

查看:79
本文介绍了缩短文本推文,而不切断链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样一个字符串:

 我爱@kevinrose的新网站< a href = http://kevinrose.com> LINK< / A> 

我有这个功能:

<$ p ($ str $($ string)$> $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ,0,$ max - 5,'utf-8')。 ...;
}返回$ string;
}

如果我将屏幕切为50,它最终会成为:

 我爱@kevinrose的新网站< a href =http:// kevinr ... 

当然会杀死html。



一个简单的方法,我可以避免削减一个href标签(之前或最好之后)而不破坏HTML?



我需要保留我的标签当然。



谢谢

解决方案

请参阅PHP:截断字符串,同时保留HTML标记和整个单词 - Alan Whipple - > http:/ /alanwhipple.com/2011/05/25/php-truncate-string-preserving-html-tags-words/

 <?php 
/ **
* truncateHtml可以将字符串截断为多个字符,同时保留整个单词和HTML标记
*
* @pa ram string $ text要截断的字符串。
* @param整数$ length返回字符串的长度,包括省略号。
* @param string $ ending结束被附加到修剪的字符串。
* @param boolean $ exact如果为false,$ text将不会被剪切为中间字符
* @param boolean $ considerHtml如果为true,则HTML标记将被正确处理
*
* @return string修剪过的字符串。
* /
函数truncateHtml($ text,$ length = 100,$ ending ='...',$ exact = false,$ considerHtml = true){
if($ considerHtml) {
//如果纯文本短于最大长度,则返回整个文本
if(strlen(preg_replace('/<。*?> /','',$ text) )< = $ length){
return $ text;
}
//将所有html标签分割为可扫描的行
preg_match_all('/(<。+?>)?([^&] *)/ s' ,$ text,$ lines,PREG_SET_ORDER);
$ total_length = strlen($ ending);
$ open_tags = array();
$ truncate ='';
foreach($ lines as $ line_matchings){
//如果此行中有任何html标记,则处理它并将其添加(不计数)到输出
if(!empty( $ line_matchings [1])){
//如果它是一个空元素,带或不带xhtml-conform关斜杠
if(preg_match('/ ^<(\s *。+? \ / \s * | \s *(IMG | BR |输入|小时|面积|基地| BASEFONT |山口|帧| ISINDEX |链路|元| PARAM)(\s +。?))GT? ; $ / is',$ line_matchings [1])){
// do nothing
// if tag is a closing tag
} else if(preg_match('/ ^ < \\ $ * / \\ /([^ \ s] +?)\s *> $ / s',$ line_matchings [1],$ tag_matchings)){
//从$ open_tags list中删除标记
$ pos = array_search($ tag_matchings [1],$ open_tags);
if($ pos!== false){
unset($ open_tags [$ pos]);
}
//如果标签是开始标签
}否则if(preg_match('/ ^ <\ s *([^ \ s>!] +)。*? > $ / s',$ line_matchings [1],$ tag_matchings)){
//将标签添加到$ open_tags列表的开头
array_unshift($ open_tags,strtolower($ tag_matchings [1]) );
}
//将html-tag添加到$ truncate'd文本
$ truncate。= $ line_matchings [1];
}
//计算行的纯文本部分的长度;将实体作为一个字符处理
$ content_length = strlen(preg_replace('/ amp; [0-9a-z] {2,8}; |&#[0-9] {1,7}; | 0-9a-f] {1,6}; / i','',$ line_matchings [2]));
if($ total_length + $ content_length> $ length){
//剩下的字符数
$ left = $ length - $ total_length;
$ entities_length = 0;
//搜索html实体
if(preg_match_all('/& [0-9a-z] {2,8}; |&#[0-9] {1,7}; | [0-9a-f] {1,6}; / i',$ line_matchings [2],$ entities,PREG_OFFSET_CAPTURE)){
//计算合法范围内所有实体的真实长度
foreach($ entities [0] as $ entity){
if($ entity [1] + 1- $ entities_length <= $ left){
$ left--;
$ entities_length + = strlen($ entity [0]);
}其他{
//不再有剩下的字符
break;
}
}
}
$ truncate。= substr($ line_matchings [2],0,$ left + $ entities_length);
//达到最大长度,因此请跳过循环
break;
} else {
$ truncate。= $ line_matchings [2];
$ total_length + = $ content_length;
}
//如果达到了最大长度,那么在循环
if($ total_length> = $ length){
break;

$ b} else {
if(strlen($ text)< = $ length){
return $ text;
} else {
$ truncate = substr($ text,0,$ length - strlen($ ending));
}
}
//如果单词不应该在中间被剪切...
if(!$ exact){
// ...搜索最后发生的空间...
$ spacepos = strrpos($ truncate,'');
if(isset($ spacepos)){
// ...并在此位置剪切文本
$ truncate = substr($ truncate,0,$ spacepos);
}
}
//将定义的结尾添加到文本
$ truncate。= $ ending;
if($ considerHtml){
//关闭所有未关闭的html-tags
foreach($ open_tags as $ tag){
$ truncate。='< /'。 $标签。 >;
}
}
return $ truncate;
}

?>

在这里也可以看到




I've got a string like this:

I love @kevinrose 's new website <a href="http://kevinrose.com">Link</a>

And I have this function:

function short($string, $max = 255) {
    if (strlen($string) >= $max) {
        $string = mb_substr($string, 0, $max - 5, 'utf-8') . '...';
    } return $string;
}

If I cut the screen at 50, it will end up being something that :

I love @kevinrose 's new website <a href="http://kevinr...

Which will of course kill the html.

Is there an easy way I can avoid cutting the a href tag (before or preferably after) without breaking the HTML ?

I need to keep my tags of course.

Thank you

解决方案

see this from PHP: Truncate string while preserving HTML tags and whole words - Alan Whipple -> http://alanwhipple.com/2011/05/25/php-truncate-string-preserving-html-tags-words/

<?php
/**
 * truncateHtml can truncate a string up to a number of characters while preserving whole words and HTML tags
 *
 * @param string $text String to truncate.
 * @param integer $length Length of returned string, including ellipsis.
 * @param string $ending Ending to be appended to the trimmed string.
 * @param boolean $exact If false, $text will not be cut mid-word
 * @param boolean $considerHtml If true, HTML tags would be handled correctly
 *
 * @return string Trimmed string.
 */
function truncateHtml($text, $length = 100, $ending = '...', $exact = false, $considerHtml = true) {
    if ($considerHtml) {
        // if the plain text is shorter than the maximum length, return the whole text
        if (strlen(preg_replace('/<.*?>/', '', $text)) <= $length) {
            return $text;
        }
        // splits all html-tags to scanable lines
        preg_match_all('/(<.+?>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER);
        $total_length = strlen($ending);
        $open_tags = array();
        $truncate = '';
        foreach ($lines as $line_matchings) {
            // if there is any html-tag in this line, handle it and add it (uncounted) to the output
            if (!empty($line_matchings[1])) {
                // if it's an "empty element" with or without xhtml-conform closing slash
                if (preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1])) {
                    // do nothing
                // if tag is a closing tag
                } else if (preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings)) {
                    // delete tag from $open_tags list
                    $pos = array_search($tag_matchings[1], $open_tags);
                    if ($pos !== false) {
                    unset($open_tags[$pos]);
                    }
                // if tag is an opening tag
                } else if (preg_match('/^<\s*([^\s>!]+).*?>$/s', $line_matchings[1], $tag_matchings)) {
                    // add tag to the beginning of $open_tags list
                    array_unshift($open_tags, strtolower($tag_matchings[1]));
                }
                // add html-tag to $truncate'd text
                $truncate .= $line_matchings[1];
            }
            // calculate the length of the plain text part of the line; handle entities as one character
            $content_length = strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
            if ($total_length+$content_length> $length) {
                // the number of characters which are left
                $left = $length - $total_length;
                $entities_length = 0;
                // search for html entities
                if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', $line_matchings[2], $entities, PREG_OFFSET_CAPTURE)) {
                    // calculate the real length of all entities in the legal range
                    foreach ($entities[0] as $entity) {
                        if ($entity[1]+1-$entities_length <= $left) {
                            $left--;
                            $entities_length += strlen($entity[0]);
                        } else {
                            // no more characters left
                            break;
                        }
                    }
                }
                $truncate .= substr($line_matchings[2], 0, $left+$entities_length);
                // maximum lenght is reached, so get off the loop
                break;
            } else {
                $truncate .= $line_matchings[2];
                $total_length += $content_length;
            }
            // if the maximum length is reached, get off the loop
            if($total_length>= $length) {
                break;
            }
        }
    } else {
        if (strlen($text) <= $length) {
            return $text;
        } else {
            $truncate = substr($text, 0, $length - strlen($ending));
        }
    }
    // if the words shouldn't be cut in the middle...
    if (!$exact) {
        // ...search the last occurance of a space...
        $spacepos = strrpos($truncate, ' ');
        if (isset($spacepos)) {
            // ...and cut the text in this position
            $truncate = substr($truncate, 0, $spacepos);
        }
    }
    // add the defined ending to the text
    $truncate .= $ending;
    if($considerHtml) {
        // close all unclosed html-tags
        foreach ($open_tags as $tag) {
            $truncate .= '</' . $tag . '>';
        }
    }
    return $truncate;
}

?>

also see here

这篇关于缩短文本推文,而不切断链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆