5

也许你们可以帮忙:

我有一个名为 $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 来搜索某个单词,比如说“作者”,它在该单词周围添加了一个 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;
    }
4

3 回答 3

4

对函数的这种更改limit_text将采用文本,如果它比给定的$length. 如果您将 a 传递$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>..."
于 2012-06-28T01:15:25.003 回答
2

首先,您需要确保不会通过缩短字符串来拆分单词。然后,您需要将所有<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>" 

如果你有更多的测试用例,或者对上面的函数有修改,请告诉我,我可以修复它!

于 2012-06-28T01:29:32.657 回答
0

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

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 个字符标记,因此它们附加在后面,以逗号分隔。

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

于 2012-06-28T06:11:31.967 回答