如果字符串长度超过110个字符,我会尝试从长文本中摘录,同时删除最后一个空格之后的所有内容。
$string = 'Стихи похожи на людей: помнят прошлое и ничего не знают о будущем, хотят жить вечно, a страница уже перелистывается.';
if (mb_strlen($string ) > 110) {
$pos = mb_strpos($string , ' ', 110);
$excerpt = rtrim(mb_substr($string, 0, $pos), '.,—-_!@\'"()*#~').'...';
}
如果我使用print_r(mb_strlen($pos));
打印,则$pos
的结果为0
,如果我将$pos
更改为$pos = mb_strpos($quote_content, ' ', 99);
,则其工作正常。
在这种情况下,最后一个单词的长度为16个字符,而整个字符串的长度为116个字符,因此对于为什么使用99偏移而上面的任何内容将产生{{1} }而不是摘录,而是返回$pos
(基于当前示例)。
我这里有很多字符串长度和单词长度不同的字符串,因此我需要一种在所有情况下都可以使用的动态解决方案。有任何想法吗?
答案 0 :(得分:1)
使用preg_replace
将字符串切成固定数量的字符的简单(快速)方法是:
$string = 'Стихи похожи на людей: помнят прошлое и ничего не знают о будущем, хотят жить вечно, a страница уже перелистывается.';
$excerpt = preg_replace('/^(.{1,110})\s.*$/u', '$1...', $string);
echo $excerpt;
输出:
Стихи похожи на людей: помнят прошлое и ничего не знают о будущем, хотят жить вечно, a страница уже...
正则表达式的工作原理是从字符串的开头一直到空格字符为止,寻找^(.{1,110})\s
个字符(从1到110)。由于量词是贪婪的,因此它需要尽可能多的字符。这些字符被分组捕获。然后,字符串的其余部分由.*$
匹配,整个字符串被第一个捕获组和三个.'s
($1...
)替换,仅给出所需的第一部分。正则表达式上的u
标志表示它将正确计数unicode字符。要调整摘录的长度,只需将110
更改为所需的长度即可。
修改
还可以通过修改正则表达式,使其坚持捕获组的最后一个字符为{{1,从而删除所有非单词字符(因此您不会以the quick brown fox,...
结尾) }}字符,然后允许以下字符成为非单词字符:
word
输出:
$string = 'Стихи похожи на людей: помнят прошлое и ничего не знают о будущем, хотят жить вечно, a страница уже перелистывается.';
$excerpt = preg_replace('/^(.{1,23}\w)\W.*$/u', '$1...', $string);
echo $excerpt;
答案 1 :(得分:1)
这将在最后一个空格处剪切字符串而不会剪切单词:
$excerpt = mb_substr($string, 0, mb_strrpos($string, ' ', -(mb_strlen($string) - 110)));
strrpos
和mb_strrpos
向后移动,因此您可以搜索从给定位置开始的最后一次出现
答案 2 :(得分:0)
通过检查110中的所有字符直到找到空间来进行懒惰修复
// lazy fix by checking all chars from 110 until space was found
if (mb_strlen($string) > 110) {
$p = 110;
while(!($pos = mb_strpos($string , ' ', $p--))){};
$excerpt = rtrim(mb_substr($string, 0, $pos), '.,—-_!@\'"()*#~') . ' ... ';
}