簡體   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