修改 php 限制文本函数,向其添加某种偏移量


Modify a php limit text function adding some kind of offset to it

也许你们可以帮忙:

我有一个名为$bio的带有生物数据的变量。

$bio = "Hello, I am John, I'm 25, I like fast cars and boats. I work as a blogger and I'm way cooler then the author of the question";

我使用一组函数搜索$bio来搜索某个单词,假设"author"在该单词周围添加一个span类,我得到:

$bio = "Hello, I am John, I'm 25, I like fast cars and boats. I work as a blogger and I'm way cooler then the <span class='"highlight'">author</span> of the question";

我使用一个函数将文本限制为 85 个字符:

$bio = limit_text($bio,85);

问题是$bio"作者"一词之前有超过 80 个字符时。应用limit_text()时,我不会看到突出显示的单词作者。

我需要的是让 limit_text() 函数正常工作,在末尾添加包含 span 类突出显示的所有单词。像这样:

*"This is the limited text to 85 chars, but there are no words with the span class highlight so I am putting to be continued ... **author**, **author2** (and all the other words that have a span class highlight around them separate by comma "*

希望你明白我的意思,如果没有,请发表评论,我会尽力解释得更好。

这是我的limit_text()函数:

function limit_text($text, $length){ // Limit Text
        if(strlen($text) > $length) {
        $stringCut = substr($text, 0, $length);
        $text = substr($stringCut, 0, strrpos($stringCut, ' '));
        }
        return $text;
    }

更新:

$xturnons = str_replace(",", ", ", $xturnons);
$xbio = str_replace(",", ", ", $xbio);
$xbio = customHighlights($xbio,$toHighlight); 
$xturnons = customHighlights($xturnons,$toHighlight);
$xbio = limit_text($xbio,85);
$xturnons = limit_text($xturnons,85);

添加 span 类的 customHighlights 函数突出显示:

function addRegEx($word){ // Highlight Words
        return "/" . $word . '[^ ,',,.,?,'.]*/i';
    }
    function highlight($word){
        return "<span class='highlighted'>".$word[0]."</span>";
    }
    function customHighlights($searchString,$toHighlight){
        $searchFor = array_map('addRegEx',$toHighlight);
        $result = preg_replace_callback($searchFor,'highlight',$searchString);
        return $result;
    }

limit_text函数的更改将获取文本,如果文本长于给定$length,则将其剪切。如果您向它传递$needle,它将搜索它的第一个出现,并以此结束您的句子。

此外,如果文本在实际长度之前被剪切,它将增加$addition,同时仍保留$length个字符的限制。

我根据您在下面给出的用法和示例输出:

<?php
/**
*   $text - The text to cut from
*   $length - The amount of characters that should be returned
*   $needle - If needle is given and found in the text, and it is 
*             at least $length far from the start of the string - it will end the sentence with it.
*   $addition - If the sentence was cut in the middle, will add it to the end of it.
**/
function limit_text($text, $length, $needle="", $addition="...") { 
    if(strlen($text) > $length) {
        $length -= strlen($addition);
        $start = 0;
        $trimLast = true;
        if (!empty($needle)) {
            $needleStart = strpos($text, $needle);
            if ($needleStart > $length) {
                $length -= strlen($needle);
                $start = $needleStart + strlen($needle) - $length;
                $trimLast = false;
            }
        }
        $stringCut = substr($text, max(0, $start), $length);
        if ($start > 0) {
            $stringCut = substr($stringCut, strpos($stringCut, ' ')+1);
        }
        if ($trimLast) {
            $lastWhitespace = strrpos($stringCut, ' ');
            $stringCut = substr($stringCut, 0, $lastWhitespace);
        }
        // split into words (so we won't replace words that contain it in the middle)
        // and wrap $needle with <span class="highlighted"></span>
        if (!empty($needle)) {
            $words = explode(" ", $stringCut);
            $needles = array_keys($words, $needle);
            foreach ($needles as $needleKey) {
                $words[$needleKey] = "<span class='"highlighted'">$needle</span>";
            }
            $stringCut = implode(" ", $words);
        }
        $text = $stringCut.$addition;
    }
    return $text;
}
$bio = "Hello, I am John, I'm 25, I like fast cars and boats. I work as a blogger and I'm way cooler then the author of the question";
$text = limit_text($bio, 85, "author");
var_dump($text);

输出

string (111) "fast cars and boats. I work as a blogger and I'm way cooler then the <span class="highlighted">author</span>..."

首先,您需要确保不会通过缩短字符串来分解单词。然后,您需要将所有<span class="highlight">标记附加到缩短字符串的末尾。这是我想到的(大约 8 行!

function limit_text($text, $length){
    if( strlen( $text) < $length) {
        return $text;
    }
    // Truncate the string without breaking words
    list( $wrapped) = explode("'n", wordwrap( $text, $length));
    // Get the span of text occurring after the wrapped string
    $remainder = substr( $text, strlen( $wrapped));
    // Add the "to be continued" to $wrapped
    $wrapped .= ' to be continued ... ';
    // Now, grab all of the <span class="highlight"></span> tags in the $remainder
    preg_match_all( '#<span class="highlight">[^<]+</span>#i', $remainder, $matches);
    // Add the <span> tags to the end of the string, separated by a comma, if present
    $wrapped .= implode( ', ', $matches[0]);
    return $wrapped;
}

现在,使用原始测试:

$bio = "Hello, I am John, I'm 25, I like fast cars and boats. I work as a blogger and I'm way cooler then the <span class='"highlight'">author</span> of the question";
$bio = limit_text( $bio,85);
var_dump( htmlentities( $bio));

这输出:

string(165) "Hello, I am John, I'm 25, I like fast cars and boats. I work as a blogger and I'm way to be continued ... <span class="highlight">author</span>"

现在,另一个具有多个<span>标签的测试:

这输出:

$bio = 'Hello, what about a <span class="highlight">span tag</span> before the limit? Or what if I have many <span class="highlight">span tags</span> <span class="highlight">after</span> <span class="highlight">the</span> limit?';
$bio = limit_text( $bio,85);
var_dump( htmlentities( $bio));
string(308) "Hello, what about a <span class="highlight">span tag</span> before the limit? Or what to be continued ... <span class="highlight">span tags</span>, <span class="highlight">after</span>, <span class="highlight">the</span>" 

如果您有更多测试用例,或者对上述功能进行了修改,请告诉我,我可以修复它!

从您的要求来看,这应该可以满足您的需求:

function get_highlighted_string($s)
{
    return '<span class="highlight">' . htmlspecialchars($s) . '</span>';
}
function limit_text($text, $max_length, array $keywords = array(), $continued = '...')
{
    // highlights to put after the cut string
    $extra = array();
    // highlight keywords
    if ($keywords) {
        $re = '~'b(' . join('|', array_map('preg_quote', $keywords, array('~'))) . ')'b~i';
        // get all matches and capture their positions as well
        if (preg_match_all($re, $text, $matches, PREG_OFFSET_CAPTURE)) {
            // we reverse the matches by position to make replacement easier
            foreach (array_reverse($matches[1]) as $match) {
                // $match[0] = match
                // $match[1] = start position
                $match_len = strlen($match[0]);
                if ($match[1] + $match_len <= $max_length) {
                    // still fits in cut string
                    $match_replacement = get_highlighted_string($match[0]);
                    $text = substr_replace($text, $match_replacement, $match[1], $match_len);
                    // update max length
                    $max_length = $max_length - $match_len + strlen($match_replacement);
                } else {
                    // will not fit in the cut string, so we place it outside
                    array_unshift($extra, get_highlighted_string($match[0]));
                }
            }
        }
        // use wordwrap and strcspn to cut the string by word boundaries
        if (strlen($text) > $max_length) {
            $text = substr($text, 0, strcspn(wordwrap($text, $max_length, "'0"), "'0")) . " $continued";
        }
    }
    if ($extra) {
        // append what we couldn't fit in the cut string
        $text .= ' ' . join(', ', $extra);
    }
    return $text;
}

例:

echo limit_text("Hello, I like fast cars and boats. I work as a blogger I'm way cooler then the author of the question", 85, array('author', 'question'));
Hello, I like fast cars and boats. I work as a blogger I'm way cooler then the <span class="highlight">author</span> ... <span class="highlight">question</span>

示例中,截止值正好在author,因此突出显示在...之前,而question关键字则放在后面。

再比如:

echo limit_text("Hello, I am John, I'm 25, I like fast cars and boats. I work as a blogger and I'm way cooler then the author of the question", 85, array('author', 'question'));
Hello, I am John, I'm 25, I like fast cars and boats. I work as a blogger and I'm way ... <span class="highlight">author</span>, <span class="highlight">question</span>

这两个关键字都超出了 85 个字符的标记,因此它们都附加在后面,逗号分隔。

让我知道这是否适合您:)