【发布时间】:2011-01-07 11:02:18
【问题描述】:
我正在从数据库中提取博客文章。我想将文本修剪为最大长度 340 个字符。
如果博客文章超过 340 个字符,我想将文本修剪到最后一个完整单词并在末尾添加“...”。
E.g.
NOT: In the begin....
BUT: In the ...
【问题讨论】:
-
如果用户输入一个长度为 341 个字符的单词(帖子中完全没有空格),你会怎么做?
我正在从数据库中提取博客文章。我想将文本修剪为最大长度 340 个字符。
如果博客文章超过 340 个字符,我想将文本修剪到最后一个完整单词并在末尾添加“...”。
E.g.
NOT: In the begin....
BUT: In the ...
【问题讨论】:
您似乎希望首先将文本精确地修剪为 340 个字符,然后找到字符串中最后一个 ' ' 的位置并修剪到该数量。像这样:
$string = substr($string, 0, 340);
$string = substr($string, 0, strrpos($string, ' ')) . " ...";
【讨论】:
其他答案向您展示了如何使文本大致 340 个字符。如果这对您来说没问题,请使用其他答案之一。
但如果您想要非常严格的最大值 340 个字符,其他答案将不起作用。您需要记住,添加 '...' 会增加字符串的长度,您需要考虑到这一点。
$max_length = 340;
if (strlen($s) > $max_length)
{
$offset = ($max_length - 3) - strlen($s);
$s = substr($s, 0, strrpos($s, ' ', $offset)) . '...';
}
还要注意,这里我使用了 strrpos 的重载,它需要一个偏移量来直接从字符串中的正确位置开始搜索,而不是首先缩短字符串。
在线查看:ideone
【讨论】:
$.='...' 会比最后一步更容易吗?
如果你启用了 mbstring 扩展(现在大多数服务器上都有),你可以使用 mb_strimwidth 函数。
echo mb_strimwidth($string, 0, 340, '...');
【讨论】:
尝试:
preg_match('/^.{0,340}(?:.*?)\b/siu', $text, $matches);
echo $matches[0] . '...';
【讨论】:
. 不匹配换行符。所以当第 340 个字符之前有换行符时,它是行不通的。最后添加一个s 修饰符就可以了。
我把约翰康德的答案放在一个方法里:
function softTrim($text, $count, $wrapText='...'){
if(strlen($text)>$count){
preg_match('/^.{0,' . $count . '}(?:.*?)\b/siu', $text, $matches);
$text = $matches[0];
}else{
$wrapText = '';
}
return $text . $wrapText;
}
例子:
echo softTrim("Lorem Ipsum is simply dummy text", 10);
/* Output: Lorem Ipsum... */
echo softTrim("Lorem Ipsum is simply dummy text", 33);
/* Output: Lorem Ipsum is simply dummy text */
echo softTrim("LoremIpsumissimplydummytext", 10);
/* Output: LoremIpsumissimplydummytext... */
【讨论】:
你可以尝试使用 PHP 自带的函数,比如自动换行
print wordwrap($text,340) . "...";
【讨论】:
function trim_characters($text, $length = 340) {
$length = (int) $length;
$text = trim( strip_tags( $text ) );
if ( strlen( $text ) > $length ) {
$text = substr( $text, 0, $length + 1 );
$words = preg_split( "/[\s]| /", $text, -1, PREG_SPLIT_NO_EMPTY );
preg_match( "/[\s]| /", $text, $lastchar, 0, $length );
if ( empty( $lastchar ) )
array_pop( $words );
$text = implode( ' ', $words );
}
return $text;
}
使用此函数 trim_characters() 将字符串修剪为指定数量的字符,优雅地停在空格处。 我认为这对你有帮助。
【讨论】:
为什么会这样?
实际正则表达式的解决方法很简单:
/^(.{0,339}\w\b)/su
PHP 中的完整方法可能如下所示:
function trim_length($text, $maxLength, $trimIndicator = '...')
{
if(strlen($text) > $maxLength) {
$shownLength = $maxLength - strlen($trimIndicator);
if ($shownLength < 1) {
throw new \InvalidArgumentException('Second argument for ' . __METHOD__ . '() is too small.');
}
preg_match('/^(.{0,' . ($shownLength - 1) . '}\w\b)/su', $text, $matches);
return (isset($matches[1]) ? $matches[1] : substr($text, 0, $shownLength)) . $trimIndicator ;
}
return $text;
}
更多解释:
$shownLength 是保持非常严格的限制(就像 Mark Byers 提到的)\w\b 部分是为了避免结尾处的空格或插入(见下面的1)In the ... 被描述为所需,但我觉得In the... 更流畅(也不喜欢In the,... 等)【讨论】:
最简单的解决方案
$text_to_be_trim= "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry standard.";
if(strlen($text_to_be_trim) > 20)
$text_to_be_trim= substr($text_to_be_trim,0,20).'....';
对于多字节文本
$stringText= "UTIL CONTROL DISTRIBUCION AMARRE CIGÜEÑAL";
$string_encoding = 'utf8';
$s_trunc = mb_substr($stringText, 0, 37, $string_encoding);
echo $s_trunc;
【讨论】: