我有一个用PHP编写的代码片段,它从数据库中提取一个文本块,并将其发送到网页上的一个小部件。原文可以是一篇很长的文章,也可以是一两个短句;但是对于这个小部件,我不能显示超过200个字符。我可以使用substr()在200个字符处切断文本,但结果将在单词中间切断——我真正想要的是在200个字符前的最后一个单词的末尾切断文本。
当前回答
找到这个问题的完美解决方案是多么棘手,这令人惊讶。我还没有在本页上找到至少在某些情况下不会失败的答案(特别是如果字符串包含换行符或制表符,或者如果单词break不是空格,或者如果字符串有UTF-8多字节字符)。
这里有一个简单的解决方案,适用于所有情况。这里也有类似的答案,但是如果希望它处理多行输入,“s”修饰符很重要,而“u”修饰符使它正确地计算UTF-8多字节字符。
function wholeWordTruncate($s, $characterCount)
{
if (preg_match("/^.{1,$characterCount}\b/su", $s, $match)) return $match[0];
return $s;
}
一个可能的边缘情况是…如果字符串的第一个$characterCount字符中没有任何空格,它将返回整个字符串。如果你喜欢在$characterCount处强制中断,即使它不是一个单词边界,你可以使用这个:
function wholeWordTruncate($s, $characterCount)
{
if (preg_match("/^.{1,$characterCount}\b/su", $s, $match)) return $match[0];
return mb_substr($return, 0, $characterCount);
}
最后一个选项,如果你想让它添加省略号如果它截断字符串…
function wholeWordTruncate($s, $characterCount, $addEllipsis = ' …')
{
$return = $s;
if (preg_match("/^.{1,$characterCount}\b/su", $s, $match))
$return = $match[0];
else
$return = mb_substr($return, 0, $characterCount);
if (strlen($s) > strlen($return)) $return .= $addEllipsis;
return $return;
}
其他回答
虽然这是一个相当老的问题,但我想我可以提供一个替代方案,因为它没有被提到,而且对PHP 4.3+有效。
您可以使用sprintf系列函数来截断文本,方法是使用%。ℕs精密修改器。
句号。后面跟着一个整数,它的含义取决于 说明符: 对于e, e, f和f说明符:这是小数点后要打印的位数(默认情况下,这是6)。 对于g和g说明符:这是要打印的有效数字的最大数量。 对于说明符:它作为一个截断点,设置字符串的最大字符限制
简单截断https://3v4l.org/QJDJU
$string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var_dump(sprintf('%.10s', $string));
结果
string(10) "0123456789"
扩展截断https://3v4l.org/FCD21
因为sprintf的功能类似于substr,并且会部分切断单词。下面的方法将通过使用strpos(wordwrap(…, '[break]'), '[break]'),并使用特殊的分隔符。这允许我们检索位置,并确保我们不匹配标准的句子结构。
返回不部分截断单词且不超过指定宽度的字符串,同时保留换行符(如果需要)。
function truncate($string, $width, $on = '[break]') {
if (strlen($string) > $width && false !== ($p = strpos(wordwrap($string, $width, $on), $on))) {
$string = sprintf('%.'. $p . 's', $string);
}
return $string;
}
var_dump(truncate('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', 20));
var_dump(truncate("Lorem Ipsum is simply dummy text of the printing and typesetting industry.", 20));
var_dump(truncate("Lorem Ipsum\nis simply dummy text of the printing and typesetting industry.", 20));
结果
/*
string(36) "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
string(14) "Lorem Ipsum is"
string(14) "Lorem Ipsum
is"
*/
使用wordwrap($string, $width)或strtok(wordwrap($string, $width), "\n")的结果
/*
string(14) "Lorem Ipsum is"
string(11) "Lorem Ipsum"
*/
这将返回单词的前200个字符:
preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, 201));
我将使用preg_match函数来做到这一点,因为您想要的是一个相当简单的表达式。
$matches = array();
$result = preg_match("/^(.{1,199})[\s]/i", $text, $matches);
表达式的意思是“匹配从长度1-200开始以空格结尾的任何子字符串”。结果在$result中,匹配在$matches中。这就解决了你最初的问题,即以任意空格结束的问题。如果你想让它以换行符结束,将正则表达式更改为:
$result = preg_match("/^(.{1,199})[\n]/i", $text, $matches);
我发现这很有效:
function abbreviate_string_to_whole_word($string, $max_length, $buffer) {
if (strlen($string) > $max_length) {
$string_cropped = substr($string, 0, $max_length - $buffer);
$last_space = strrpos($string_cropped, " ");
if ($last_space > 0) {
$string_cropped = substr($string_cropped, 0, $last_space);
}
$abbreviated_string = $string_cropped . " ...";
}
else {
$abbreviated_string = $string;
}
return $abbreviated_string;
}
缓冲区允许您调整返回字符串的长度。
你可以用这个:
function word_shortener($text, $words=10, $sp='...'){
$all = explode(' ', $text);
$str = '';
$count = 1;
foreach($all as $key){
$str .= $key . ($count >= $words ? '' : ' ');
$count++;
if($count > $words){
break;
}
}
return $str . (count($all) <= $words ? '' : $sp);
}
例子:
word_shortener("Hello world, this is a text", 3); // Hello world, this...
word_shortener("Hello world, this is a text", 3, ''); // Hello world, this
word_shortener("Hello world, this is a text", 3, '[read more]'); // Hello world, this[read more]
Edit
工作原理:
1. 从输入文本中打开空格:
$all = explode(' ', $text);
例如,如果$text将是"Hello world",那么$all是一个带有爆炸值的数组:
“你好”,“世界”)
2. 对于每个单词:
选择展开文本中的每个元素:
foreach($all as $key){...
将当前单词($key)附加到$str,如果它是最后一个单词,则添加空格:
$str .= $key . ($count >= $words ? '' : ' ');
然后给$count加上1,检查它是否大于max limit($words)打破循环:
if($count > $words){
break;
}
只有当最终文本小于输入文本时,才返回$str和分隔符($sp):
return $str . (count($all) <= $words ? '' : $sp);
推荐文章
- Printf与std::字符串?
- 不区分大小写的“in”
- 原则-如何打印出真正的sql,而不仅仅是准备好的语句?
- 如何从关联PHP数组中获得第一项?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- PHP/MySQL插入一行然后获取id
- 我如何排序一个多维数组在PHP
- 如何在PHP中截断字符串最接近于一定数量的字符?
- PHP错误:“zip扩展名和unzip命令都没有,跳过。”
- Nginx提供下载。php文件,而不是执行它们
- Json_encode()转义正斜杠
- 如何在PHP中捕获cURL错误
- Ruby数组到字符串的转换
- 为什么在Java和。net中不能修改字符串?
- 如何要求一个分叉与作曲家?