繁体   English   中英

PHP通过在x字符后的最后一个空格上剪切字符串来摘录

[英]PHP Make an excerpt by cutting the string on the last space after x characters

我正在尝试从长文本中摘录,同时删除最后一个空格后的所有内容,如果字符串长度超过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));打印print_r(mb_strlen($pos)); $pos的结果为0 ,如果我将$pos更改$pos $pos = mb_strpos($quote_content, ' ', 99); ,它的工作正常$pos = mb_strpos($quote_content, ' ', 99);

在这种情况下,最后一个单词是16个字符长,整个字符串长度为116个字符,因此很好地理解为什么99偏移量有效,而上面的任何内容都会导致$pos值为0因此而不是做一个摘录它只返回... (基于当前的例子)。

我这里有很多字符串,字符串长度和字长不同,所以我需要一个可以在所有情况下都能运行的动态解决方案。 有任何想法吗?

使用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更改为您需要的任何长度。

Regex101演示

编辑

正则表达式也可以修改为剥离任何非单词字符(因此你不会the quick brown fox,... ),通过修改它来坚持捕获组的最后一个字符是word字符和然后允许以下字符为非单词字符:

$string = 'Стихи похожи на людей: помнят прошлое и ничего не знают о будущем, хотят жить вечно, a страница уже перелистывается.';
$excerpt = preg_replace('/^(.{1,23}\w)\W.*$/u', '$1...', $string);
echo $excerpt;

输出:

Стихи похожи на людей...

更新的演示

这将在最后一个空格处剪切字符串而不切换单词:

$excerpt = mb_substr($string, 0, mb_strrpos($string, ' ', -(mb_strlen($string) - 110)));

strrposmb_strrpos向后移动,以便您可以从给定位置开始搜索最后一个匹配项

通过检查从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), '.,—-_!@\'"()*#~') . ' ... ';
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM