也许你们可以帮忙:
我有一个名为$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 个字符的标记,因此它们都附加在后面,逗号分隔。
让我知道这是否适合您:)