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

修改php限制文本函数,向其添加某种偏移量,php,Php,也许你们可以帮忙: 我有一个名为$bio的变量,其中包含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

也许你们可以帮忙:

我有一个名为$bio的变量,其中包含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";
问题是,$bio中的“author”一词前面的字符数超过80个。 当应用
limit\u text()
时,我不会看到突出显示的单词author

我需要的是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\u 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);
string (111) "fast cars and boats. I work as a blogger and I'm way cooler then the <span class="highlighted">author</span>..."
customHighlights
函数,用于添加突出显示的span类:

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;
    }
函数addRegEx($word){//突出显示单词
返回“/“$word.[^,\,,,?,\.]*/i”;
}
功能突出显示($word){
返回“$word[0]”;
}
函数customHighlights($searchString,$toHighlight){
$searchFor=array_map('addRegEx',$toHighlight);
$result=preg_replace_回调($searchFor,'highlight',$searchString);
返回$result;
}

限制\u文本
功能的此更改将获取文本,如果文本长度超过给定的
$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);

首先,您需要确保不会通过缩短字符串将单词分开。然后需要将所有
标记附加到缩短字符串的末尾。以下是我的想法(大约在8行中!):

函数限制\u text($text,$length){
如果(strlen($text)<$length){
返回$text;
}
//截断字符串而不打断单词
列表($wrapped)=分解(“\n”,字包装($text,$length));
//获取换行字符串后出现的文本范围
$rements=substr($text,strlen($wrapped));
//将“待续”添加到$wrapped
$wrapped.=“待续…”;
//现在,抓取$rements中的所有标记

preg#u match_all('#[^从您的需求判断,这应该满足您的需求:

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;
}
这两个关键字都超出了85个字符的标记,因此它们被附加在后面,以逗号分隔


让我知道这对你是否有效:)

你需要理顺你的要求:如果“作者”是86个单词中的第86个?150个单词中的第100个?200个单词中的第100个?等等,你希望它做什么。一旦你决定了行为应该是什么,实现它应该很容易!如果“作者”是150个单词(假设所有150个单词都有800个字符),作者有5个字符,限制文本应该从字符715开始,到字符800结束,包含作者单词。@John3136,我认为OP需要这样的东西,比如说关键字是FOO,限制是12,句子是bar baz FOO bim boom,结果应该是*baz FOO bim*是的,确切地说,有什么想法吗?根据我的第一条评论:rul是什么是吗?为什么“巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴巴在结果中?可以有多个突出显示的单词吗?-如果两个突出显示的单词相隔90个字符怎么办?-除非你能清楚地说出你想做什么,否则你几乎没有机会做到!他就像那个问题记录者一样;)几年前读过一篇关于他坐在海滩上通过博客赚钱的帖子。顺便说一句,我有几个问题:1.我能有更多像author1、author2、author3这样的价值观吗?如果文本中有针,它会以针结尾。--它应该保持85个字符的长度…例如,如果作者是我不想让这个句子在达到85之前结束的第二个词chars@webmasters:我想进一步编辑,当给定多个值时,预期的行为是什么?Ty非常感谢,我只是一个网站管理员而不是程序员,我看不到自己在做这些事情:)…在前85个字符内突出显示它们并添加不在后面的,用comma@webmasters-当然!如果您发现一个测试用例破坏了它,请将其与错误的解释一起发布,以便我可以修改该函数。请注意,我刚刚更新了该函数,使其与PHP版本<5.4兼容。测试它是否有效除了:将标记添加到字符串的末尾,以逗号,如果present@webmasters-它应该与该测试用例一起工作,请参见我的第二个示例-它有多个
标记,它们都添加到字符串的末尾,并用逗号分隔。您可以发布您使用的确切字符串以及所需的输出吗?我使用“highlighted”类而不是“highlight”,修改后仍然不起作用…让我发布准确的代码。一秒钟。我已经用我使用的所有代码更新了问题,请看一看。代码在85个字符的限制范围内工作,但不会在末尾添加标记。
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>"
$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>
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>