如何将PHP中的字符串截断为最接近一定数量字符的单词?
Posted
技术标签:
【中文标题】如何将PHP中的字符串截断为最接近一定数量字符的单词?【英文标题】:How to Truncate a string in PHP to the word closest to a certain number of characters? 【发布时间】:2010-09-09 22:43:24 【问题描述】:我有一个用 php 编写的代码 sn-p,它从数据库中提取一段文本并将其发送到网页上的小部件。原始文本块可以是一篇冗长的文章,也可以是一两句话;但是对于这个小部件,我不能显示超过 200 个字符。我可以使用 substr() 在 200 个字符处截断文本,但结果会在单词中间截断——我真正想要的是在最后一个 word 末尾截断文本i> 在 200 个字符之前。
【问题讨论】:
该问题旨在说明截断的文本将适合网页上某些固定数量的像素。在这种情况下,根据所选字体,每个字符所需的空间不是恒定的。因此我们不能假设 200 个字符最适合可用像素。到目前为止(直到 2011 年 3 月 2 日),以下所有答案都缺少这一点,因此它们都没有提供可靠的解决方案。 -:( 不,不是。您可以以可靠的方式设置字体,然后测量最坏的情况,也就是可以容纳多少最宽的字符。如果您需要 100% 确定浏览器是如何呈现它的,那么无论如何这不再是 PHP 问题了。跨度> 试试这个链接,可以帮到你***.com/a/26098951/3944217 您可能会发现s($str)->truncateSafely(200)
很有帮助,如this standalone library 中所示。
【参考方案1】:
通过使用wordwrap 函数。它将文本拆分为多行,使得最大宽度是您指定的宽度,在单词边界处中断。拆分后,只需取第一行:
substr($string, 0, strpos(wordwrap($string, $your_desired_width), "\n"));
oneliner 无法处理的一件事是文本本身短于所需宽度的情况。要处理这种极端情况,应该执行以下操作:
if (strlen($string) > $your_desired_width)
$string = wordwrap($string, $your_desired_width);
$string = substr($string, 0, strpos($string, "\n"));
如果文本在实际剪切点之前包含换行符,则上述解决方案存在过早剪切文本的问题。这里有一个解决这个问题的版本:
function tokenTruncate($string, $your_desired_width)
$parts = preg_split('/([\s\n\r]+)/', $string, null, PREG_SPLIT_DELIM_CAPTURE);
$parts_count = count($parts);
$length = 0;
$last_part = 0;
for (; $last_part < $parts_count; ++$last_part)
$length += strlen($parts[$last_part]);
if ($length > $your_desired_width) break;
return implode(array_slice($parts, 0, $last_part));
另外,这里是用于测试实现的 PHPUnit 测试类:
class TokenTruncateTest extends PHPUnit_Framework_TestCase
public function testBasic()
$this->assertEquals("1 3 5 7 9 ",
tokenTruncate("1 3 5 7 9 11 14", 10));
public function testEmptyString()
$this->assertEquals("",
tokenTruncate("", 10));
public function testShortString()
$this->assertEquals("1 3",
tokenTruncate("1 3", 10));
public function testStringTooLong()
$this->assertEquals("",
tokenTruncate("toooooooooooolooooong", 10));
public function testContainingNewline()
$this->assertEquals("1 3\n5 7 9 ",
tokenTruncate("1 3\n5 7 9 11 14", 10));
编辑:
不处理特殊的 UTF8 字符,如“à”。在 REGEX 末尾添加 'u' 来处理它:
$parts = preg_split('/([\s\n\r]+)/u', $string, null, PREG_SPLIT_DELIM_CAPTURE);
【讨论】:
如果在所需宽度之前有\n
,这似乎会过早地剪切文本。
@KendallHopkins:确实,确实存在问题。我用解决给定问题的替代实现更新了答案。
此示例是否适用于包含 html 标签(如段落标签)的字符串?
它对我真的很有帮助,我的头疼很长,Arabic
字母现在在tokenTruncate
函数的帮助下变成了正确的单词.. tnx 一百万:)
为什么不添加: if(strlen($string)
【参考方案2】:
这将返回单词的前 200 个字符:
preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, 201));
【讨论】:
差不多。无论如何,它似乎为我删除了句子的最后一个词。 效果很好,但我发现与 ReX357 相同的错误。超过 1 个单词时,删除最后一个单词。 只需将其包装在检查中以确保字符串比您正在测试的字符串长(与接受的答案相同)if (strlen($string) > $your_desired_width) preg_replace(...);
我编辑了答案以包含@BlairMcMillan 建议
对正则表达式的微小改进:括号使最后的 \S+ 对匹配是可选的,但它们也捕获了这些字符。由于我们不需要捕获这些字符,因此使括号不被捕获,如下所示:/\s+?(?:\S+)?$/
【参考方案3】:
$WidgetText = substr($string, 0, strrpos(substr($string, 0, 200), ' '));
你有它 - 一种将任何字符串截断为最接近的整个单词的可靠方法,同时保持在最大字符串长度以下。
我已经尝试了上面的其他示例,但它们没有产生预期的结果。
【讨论】:
如果给定字符串的长度小于最大长度,这将切断所有内容,直到最后一个空格。为避免这种情况,请将其包装在if
语句中:if (strlen($str) > 200) ...
简单,可能比其他解决方案快得多。
一个问题是如果字符串不包含空格,它会返回一个空字符串。
可以简化为:$WidgetText = substr($string, 0, strpos($string, ' ', 200));
【参考方案4】:
当我注意到wordwrap函数的$break参数时,以下解决方案诞生了:
字符串自动换行(字符串 $str [, int $width = 75 [, string $break = "\n" [, bool $cut = false ]]])
这里是解决方案:
/**
* Truncates the given string at the specified length.
*
* @param string $str The input string.
* @param int $width The number of chars at which the string will be truncated.
* @return string
*/
function truncate($str, $width)
return strtok(wordwrap($str, $width, "...\n"), "\n");
示例 #1。
print truncate("This is very long string with many chars.", 25);
上面的例子会输出:
This is very long string...
示例 #2。
print truncate("This is short string.", 25);
上面的例子会输出:
This is short string.
【讨论】:
如果字符串已经有换行符(例如,如果您尝试提取博客文章的description
),则此方法不起作用
@supersan 始终可以使用 preg_replace('/\s+/', ' ', $description)
进行预处理,以将所有空白字符替换为单个空格;)【参考方案5】:
请记住,当您在任何地方使用“单词”进行拆分时,某些语言(例如中文和日语)不使用空格字符来拆分单词。此外,恶意用户可以简单地输入不带任何空格的文本,或者使用与标准空格字符相似的 Unicode,在这种情况下,您使用的任何解决方案都可能最终显示整个文本。解决此问题的一种方法可能是在正常将字符串拆分为空格后检查字符串长度,然后,如果字符串仍高于异常限制 - 在这种情况下可能为 225 个字符 - 继续在该限制处将其愚蠢地拆分。
当涉及到非 ASCII 字符时,还有一个注意事项;包含它们的字符串可能会被 PHP 的标准 strlen() 解释为比实际更长,因为单个字符可能占用两个或多个字节,而不仅仅是一个。如果你只是使用 strlen()/substr() 函数来分割字符串,你可能会在一个字符的中间分割一个字符串!如果有疑问,mb_strlen()/mb_substr() 会更简单一些。
【讨论】:
【参考方案6】:使用 strpos 和 substr:
<?php
$longString = "I have a code snippet written in PHP that pulls a block of text.";
$truncated = substr($longString,0,strpos($longString,' ',30));
echo $truncated;
这将为您提供一个在 30 个字符后的第一个空格处截断的字符串。
【讨论】:
您好,如果没有空格的字符串长度小于 30 则返回错误。这里的结果将是前 31 个字符而不是 30..【参考方案7】:给你:
function neat_trim($str, $n, $delim='…')
$len = strlen($str);
if ($len > $n)
preg_match('/(.' . $n . '.*?)\b/', $str, $matches);
return rtrim($matches[1]) . $delim;
else
return $str;
【讨论】:
谢谢,我发现你的功能是所有这些答案中最有用和最可靠的功能,可以满足我的需求。但是,我怎样才能让它支持多字节字符串呢? 好像支持多字节【参考方案8】:这是我基于@Cd-MaN 方法的函数。
function shorten($string, $width)
if(strlen($string) > $width)
$string = wordwrap($string, $width);
$string = substr($string, 0, strpos($string, "\n"));
return $string;
【讨论】:
【参考方案9】:$shorttext = preg_replace('/^([\s\S]1,200)[\s]+?[\s\S]+/', '$1', $fulltext);
说明:
^
- 从字符串的开头开始
([\s\S]1,200)
- 获取 1 到 200 个任意字符
[\s]+?
- 短文本末尾不包含空格,因此我们可以避免使用word ...
而不是word...
[\s\S]+
- 匹配所有其他内容
测试:
regex101.com
让我们添加到or
其他几个r
regex101.com
orrrr
正好 200 个字符。
regex101.com
在第五个 r
orrrrr
之后排除。
享受吧。
【讨论】:
我不懂 PHP 文档。我知道$1
是“替代品”,但在这个特定的上下文中它指的是什么?一个空变量?
@Anthony $1
引用匹配括号内的 ([\s\S]1,200)
。 $2
将引用第二对括号(如果有任何模式)。【参考方案10】:
令人惊讶的是,要找到这个问题的完美解决方案是多么棘手。我还没有在此页面上找到至少在某些情况下不会失败的答案(特别是如果字符串包含换行符或制表符,或者如果单词 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;
【讨论】:
我完全同意你的观点,你的似乎是少有的适用于所有 unicode 语言的例子之一。干得好! 我已经根据您的回答在这里推送了一个示例:github.com/thlib/php-truncate-words 它变成了一条线,您能快速查找错误吗?【参考方案11】:我会使用 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);
【讨论】:
字符类不用自己写\s
或\n
。不需要不区分大小写的模式修饰符,因为您的模式中没有表示字母。【参考方案12】:
好的,所以我根据上述答案得到了另一个版本,但考虑到了更多的东西(utf-8、\n 和   ;),如果与 wp 一起使用,还有一行删除了注释的 wordpress 短代码。
function neatest_trim($content, $chars)
if (strlen($content) > $chars)
$content = str_replace(' ', ' ', $content);
$content = str_replace("\n", '', $content);
// use with wordpress
//$content = strip_tags(strip_shortcodes(trim($content)));
$content = strip_tags(trim($content));
$content = preg_replace('/\s+?(\S+)?$/', '', mb_substr($content, 0, $chars));
$content = trim($content) . '...';
return $content;
【讨论】:
【参考方案13】:这是对 mattmac 的回答的一个小修复:
preg_replace('/\s+?(\S+)?$/', '', substr($string . ' ', 0, 201));
唯一的区别是在 $string 的末尾添加一个空格。这样可以确保不会按照 ReX357 的评论截断最后一个词。
我没有足够的代表点数来添加评论。
【讨论】:
【参考方案14】:/*
Cut the string without breaking any words, UTF-8 aware
* param string $str The text string to split
* param integer $start The start position, defaults to 0
* param integer $words The number of words to extract, defaults to 15
*/
function wordCutString($str, $start = 0, $words = 15 )
$arr = preg_split("/[\s]+/", $str, $words+1);
$arr = array_slice($arr, $start, $words);
return join(' ', $arr);
用法:
$input = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna liqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.';
echo wordCutString($input, 0, 10);
这将输出前 10 个单词。
preg_split
函数用于将字符串拆分为子字符串。使用正则表达式模式指定分割字符串的边界。
preg_split
函数有 4 个参数,但现在只有前 3 个与我们相关。
第一个参数——模式
第一个参数是分割字符串的正则表达式模式。在我们的例子中,我们希望跨单词边界分割字符串。因此我们使用预定义的字符类\s
,它匹配空格、制表符、回车和换行等空白字符。
第二个参数——输入字符串 第二个参数是我们要拆分的长文本字符串。
第三个参数——极限
第三个参数指定应该返回的子字符串的数量。如果将限制设置为n
,preg_split 将返回一个包含 n 个元素的数组。第一个 n-1
元素将包含子字符串。最后一个 (n th)
元素将包含字符串的其余部分。
【讨论】:
【参考方案15】:你可以用这个:
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]
【讨论】:
【参考方案16】:基于@Justin Poliey 的正则表达式:
// Trim very long text to 120 characters. Add an ellipsis if the text is trimmed.
if(strlen($very_long_text) > 120)
$matches = array();
preg_match("/^(.1,120)[\s]/i", $very_long_text, $matches);
$trimmed_text = $matches[0]. '...';
【讨论】:
***.com/questions/79960/…【参考方案17】:我有一个功能几乎可以满足您的需求,如果您进行一些编辑,它将完全适合:
<?php
function stripByWords($string,$length,$delimiter = '<br>')
$words_array = explode(" ",$string);
$strlen = 0;
$return = '';
foreach($words_array as $word)
$strlen += mb_strlen($word,'utf8');
$return .= $word." ";
if($strlen >= $length)
$strlen = 0;
$return .= $delimiter;
return $return;
?>
【讨论】:
【参考方案18】:这就是我的做法:
$string = "I appreciate your service & idea to provide the branded toys at a fair rent price. This is really a wonderful to watch the kid not just playing with variety of toys but learning faster compare to the other kids who are not using the BooksandBeyond service. We wish you all the best";
print_r(substr($string, 0, strpos(wordwrap($string, 250), "\n")));
【讨论】:
【参考方案19】:虽然这是一个相当老的问题,但我想我会提供一个替代方案,因为它没有被提及并且对 PHP 4.3+ 有效。
您可以使用sprintf
系列函数截断文本,方法是使用%.ℕs
精度修饰符。
句点
对于 e、E、f 和 F 说明符:这是要在小数点后打印的位数(默认为 6)。 对于 g 和 G 说明符:这是要打印的最大有效位数。 对于 s 说明符:它充当截止点,为字符串设置最大字符限制.
后跟一个整数,其含义取决于 说明符:
简单截断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"
*/
【讨论】:
【参考方案20】:// a looonnng string ...
$str = "Le Lorem Ipsum est simplement du
faux texte employé dans la composition et
la mise en page avant impression.
Le Lorem Ipsum est le faux texte standard de
l'imprimerie depuis les années 1500, quand un
imprimeur anonyme assembla ensemble des morceaux
de texte pour réaliser un livre spécimen de polices
de texte. Il n'a pas fait que survivre cinq siècles,
mais s'est aussi adapté à la bureautique informatique,
sans que son contenu n'en soit modifié. Il a été
popularisé dans les années 1960 grâce à la vente
de feuilles Letraset contenant des passages du
Lorem Ipsum, et, plus récemment, par son inclusion
dans des applications de mise en page de texte,
comme Aldus PageMaker";
// number chars to cut
$number_to_cut = 300;
// string truncated in one line !
$truncated_string =
substr($str, 0, strrpos(substr($str, 0, $number_to_cut), ' '));
// test return
echo $truncated_string;
// variation (add ellipsis) : echo $truncated_string.' ...';
// output :
/* Le Lorem Ipsum est simplement du
faux texte employé dans la composition et
la mise en page avant impression.
Le Lorem Ipsum est le faux texte standard de
l'imprimerie depuis les années 1500, quand un
imprimeur anonyme assembla ensemble des morceaux
de texte pour réaliser un livre
*/
【讨论】:
【参考方案21】:我知道这是旧的,但是...
function _truncate($str, $limit)
if(strlen($str) < $limit)
return $str;
$uid = uniqid();
return array_shift(explode($uid, wordwrap($str, $limit, $uid)));
【讨论】:
这个答案缺少教育解释。为什么我们在这里看到uniqid()
?【参考方案22】:
我创建了一个更类似于 substr 的函数,并且使用了@Dave 的思想。
function substr_full_word($str, $start, $end)
$pos_ini = ($start == 0) ? $start : stripos(substr($str, $start, $end), ' ') + $start;
if(strlen($str) > $end) $pos_end = strrpos(substr($str, 0, ($end + 1)), ' '); // IF STRING SIZE IS LESSER THAN END
if(empty($pos_end)) $pos_end = $end; // FALLBACK
return substr($str, $pos_ini, $pos_end);
Ps.: 全长剪切可能小于 substr.
【讨论】:
【参考方案23】:在Dave 和AmalMurali 的代码中添加了 IF/ELSEIF 语句,用于处理不带空格的字符串
if ((strpos($string, ' ') !== false) && (strlen($string) > 200))
$WidgetText = substr($string, 0, strrpos(substr($string, 0, 200), ' '));
elseif (strlen($string) > 200)
$WidgetText = substr($string, 0, 200);
【讨论】:
【参考方案24】:据我所知,这里所有的解决方案都只对起点固定的情况有效。
允许您转这个:
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna liqua. Ut enim ad minim veniam.
进入这个:
Lorem ipsum dolor sit amet, consectetur...
如果您想截断一组特定关键字周围的字词怎么办?
截断一组特定关键字周围的文本。
目标是能够转换这个:
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna liqua. Ut enim ad minim veniam.
进入这个:
...consectetur adipisicing elit, sed do eiusmod tempor...
在显示搜索结果、摘录等时,这是一种很常见的情况。要实现这一点,我们可以结合使用这两种方法:
/**
* Return the index of the $haystack matching $needle,
* or NULL if there is no match.
*
* This function is case-insensitive
*
* @param string $needle
* @param array $haystack
* @return false|int
*/
function regexFindInArray(string $needle, array $haystack): ?int
for ($i = 0; $i < count($haystack); $i++)
if (preg_match('/' . preg_quote($needle) . '/i', $haystack[$i]) === 1)
return $i;
return null;
/**
* If the keyword is not present, it returns the maximum number of full
* words that the max number of characters provided by $maxLength allow,
* starting from the left.
*
* If the keyword is present, it adds words to both sides of the keyword
* keeping a balanace between the length of the suffix and the prefix.
*
* @param string $text
* @param string $keyword
* @param int $maxLength
* @param string $ellipsis
* @return string
*/
function truncateWordSurroundingsByLength(string $text, string $keyword,
int $maxLength, string $ellipsis): string
if (strlen($text) < $maxLength)
return $text;
$pattern = '/' . '^(.*?)\s' .
'([^\s]*' . preg_quote($keyword) . '[^\s]*)' .
'\s(.*)$' . '/i';
preg_match($pattern, $text, $matches);
// break everything into words except the matching keywords,
// which can contain spaces
if (count($matches) == 4)
$words = preg_split("/\s+/", $matches[1], -1, PREG_SPLIT_NO_EMPTY);
$words[] = $matches[2];
$words = array_merge($words,
preg_split("/\s+/", $matches[3], -1, PREG_SPLIT_NO_EMPTY));
else
$words = preg_split("/\s+/", $text, -1, PREG_SPLIT_NO_EMPTY);
// find the index of the matching word
$firstMatchingWordIndex = regexFindInArray($keyword, $words) ?? 0;
$length = false;
$prefixLength = $suffixLength = 0;
$prefixIndex = $firstMatchingWordIndex - 1;
$suffixIndex = $firstMatchingWordIndex + 1;
// Initialize the text with the matching word
$text = $words[$firstMatchingWordIndex];
while (($prefixIndex >= 0 or $suffixIndex <= count($words))
and strlen($text) < $maxLength and strlen($text) !== $length)
$length = strlen($text);
if (isset($words[$prefixIndex])
and (strlen($text) + strlen($words[$prefixIndex]) <= $maxLength)
and ($prefixLength <= $suffixLength
or strlen($text) + strlen($words[$suffixIndex]) <= $maxLength))
$prefixLength += strlen($words[$prefixIndex]);
$text = $words[$prefixIndex] . ' ' . $text;
$prefixIndex--;
if (isset($words[$suffixIndex])
and (strlen($text) + strlen($words[$suffixIndex]) <= $maxLength)
and ($suffixLength <= $prefixLength
or strlen($text) + strlen($words[$prefixIndex]) <= $maxLength))
$suffixLength += strlen($words[$suffixIndex]);
$text = $text . ' ' . $words[$suffixIndex];
$suffixIndex++;
if ($prefixIndex > 0)
$text = $ellipsis . ' ' . $text;
if ($suffixIndex < count($words))
$text = $text . ' ' . $ellipsis;
return $text;
现在你可以这样做了:
$text = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do' .
'iusmod tempor incididunt ut labore et dolore magna liqua. Ut enim' .
'ad minim veniam.';
$text = truncateWordSurroundingsByLength($text, 'elit', 25, '...');
var_dump($text); // string(32) "... adipisicing elit, sed do ..."
Run code.
【讨论】:
您似乎扩大了这个问题的范围,这导致了一个非常复杂的答案,不太可能帮助导航到此页面的研究人员。如果您将答案移至更合适的页面,或者如果没有,则发布您自己的问题并自行回答可能会更好。此外,[^\s]
更简单地表示为\S
。我通常避免在 php 中使用 or
和 and
以防止出现优先级问题。 preg_quote()
没有默认分隔符,因此您应该提供一个。【参考方案25】:
我觉得这行得通:
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;
缓冲区允许您调整返回字符串的长度。
【讨论】:
【参考方案26】:function trunc($phrase, $max_words)
$phrase_array = explode(' ',$phrase);
if(count($phrase_array) > $max_words && $max_words > 0)
$phrase = implode(' ',array_slice($phrase_array, 0, $max_words)).'...';
return $phrase;
【讨论】:
不回答问题,计算单词而不是字符。 这个答案没有解释它为什么起作用,如何从中学习?【参考方案27】:我以前用过这个
<?php
$your_desired_width = 200;
$string = $var->content;
if (strlen($string) > $your_desired_width)
$string = wordwrap($string, $your_desired_width);
$string = substr($string, 0, strpos($string, "\n")) . " More...";
echo $string;
?>
【讨论】:
【参考方案28】:你可以试试这个
substr( $str, 0, strpos($str, ' ', 200) );
【讨论】:
其他答案中已经提到了该解决方案。它的问题是如果字符串小于 200 个字符长度,或者它不包含任何空格,它就会失败。它也不将字符串限制为 200 个字符,而是在 200 个字符之后的空格处断开字符串,这通常不是您想要的。【参考方案29】:我相信这是最简单的方法:
$lines = explode('♦♣♠',wordwrap($string, $length, '♦♣♠'));
$newstring = $lines[0] . ' • • •';
我正在使用特殊字符来分割文本并剪切它。
【讨论】:
【参考方案30】:使用这个:
以下代码将删除“,”。如果您有任何其他字符或子字符串,您可以使用它来代替 ','
substr($string, 0, strrpos(substr($string, 0, $comparingLength), ','))
//如果你有另一个字符串帐户
substr($string, 0, strrpos(substr($string, 0, $comparingLength-strlen($currentString)), ','))
【讨论】:
以上是关于如何将PHP中的字符串截断为最接近一定数量字符的单词?的主要内容,如果未能解决你的问题,请参考以下文章
将非 ASCII 字符(变音符号、重音符号...)转换为最接近的 ASCII 等效字符(创建 slug)
将给定数组中的所有零移动到末尾,并将每个非零元素替换为最接近的较大值(如果有)