【问题标题】:Cull a text field by certain amount of characters while making sure not to cut off words按一定数量的字符剔除文本字段,同时确保不截断单词
【发布时间】:2012-10-17 06:22:06
【问题描述】:

因此,在创建从数据库中提取页面信息的动态网站时,我遇到了一个很常见的问题。假设您在首页上有一个滑块,显示 8 个最近的博客/故事帖子。服务器获取每一个的标题、说明和文本字段,但我们不想将文章的全文返回给浏览器,那样会很浪费。所以我猜你会做的是使用递归函数在一定数量的字符处切断文本字段,但我似乎无法弄清楚我做错了什么。代码如下:

$string = strip_tags("<p>Jackson expects to practice on Wednesday for the first time since getting hurt in a season-opening game agains the Chicago Bears. The teams medical advisor says his sprained ankle has healed fast then expected, although he warns to err on the side of caution.</p><p>Coach Andy Reid is optimistic he can get Jackson ready in time for next Monday's square off vs the Detroit Lions, though he states that he doesn't want to take the risk of loosing him for the start of the playoffs in 3 weeks.</p>");
$count = 0;

echo $string."<br />";

function trim_string($string, $max_length, $search_char){
    global $count;
    $pos = strripos($string, $search_char);
    $new_string = substr($string, 0, $pos);
    $length = strlen($new_string);  

    if($length > $max_length){      
        $count++;
        trim_string($new_string, 120, ' ');
    }else{
        return $new_string; 
    }   
}

$trimmed_string = trim_string($string, 120, ' ');

echo $count."<br />".substr_count($string, ' ')."<br />".$trimmed_string;

如您所见,我正在尝试调试。 Count 返回 67,而原始的出现次数是 86,所以我知道它正在工作,但是 $trimmed_string 没有任何回声。

如果有人有任何想法或做这种事情的更好方法,请告诉我!

【问题讨论】:

  • 我只是让函数在它再次调用自己之前回显出新字符串,并且知道它确实在工作,但我不明白为什么它在缩短它后不返回这个字符串。

标签: php string recursion trim


【解决方案1】:

这不一定需要递归。

function trim_string($string, $max_length, $search_char)
{
    $string = substr($string, 0, $max_length);
    $last_index = strrpos($string, $search_char);
    return substr($string, 0, $last_index);
}

这是一个基本的想法。如果您在不是空格或其他东西的地方切碎,它可能会在最后给您一个空白空间。

而且,它没有回显,因为您需要返回递归。

if($length > $max_length){      
    $count++;
    return trim_string($new_string, 120, ' ');
}else{
    return $new_string; 
}  

【讨论】:

  • 我知道必须有一种更简单的方法,以及我的值没有返回递归的原因。谢谢!
  • 问题,我想知道,PHP 中内置的一些字符串函数本身是递归的吗?另外,我认为在大规模设置中,在存储在数据库中并将这个较小的字符串保存在单独的字段中时运行一次该函数可能是有意义的。这种额外的数据库开销可能比在每个页面调用上运行这样的函数要高效得多,并且比必须将完整文章的文本发送到客户端以在用户端运行类似的函数要高效得多。
  • 是的,在运行这样的东西时存储在数据库中是有意义的,尤其是在循环中。但是,如果您在更新时将动态页面写入平面文本,那么这并不重要。我会存储在数据库中并亲自写入纯文本。我总是更喜欢在可能的情况下动态提供预渲染的 html。
【解决方案2】:

如果我是你,我不会执行递归函数 简单的功能 这将做到这一点

  • explode " " 是的,它是一个空格

  • 每个字符串的count字符后

    ..让我告诉你

    $array = explode(" ",$string); //让我们说

    $max_length =50; $输出=""; foreach($array 作为 $value){ if(strlen($output.$value) > $max_length) 中断; 否则 $output.=$value; }

    回显$输出;

你怎么看?

【讨论】:

  • 嗯,我不确定我是否很好地遵循了您的代码,但这可以追溯到我上面提出的问题。像explode这样的函数肯定是某种递归函数,不是吗?将所有这些部分分解成一个数组,然后遍历该数组似乎对 CPU 来说是额外的工作。虽然我不是计算机科学专业哈哈,但我喜欢思考这些事情。
【解决方案3】:

试试这个尺寸:

/**
* Keeps a (maximum or minimum) number of characters from a string.
* Will not break words in the process.
*
* If $RightBound === true the $Length is the maximum allowed.
* If $RightBound === false the $Length is the minimum allowed.
* 
* @param string $String
* @param int $Length
* @param bool $RightBound
* @return string
*/
function ChunkWordsByLength($String, $Length, $Bound = true){
    if(!is_string($String)){
        trigger_error('$String must be a string.', E_USER_WARNING);
        return false;
    }
    if(!is_numeric($Length) or (($Length = intval($Length)) < 1)){
        trigger_error('$Length must be a positive integer.', E_USER_WARNING);
        return false;
    }
    if(strlen($String) <= $Length){
        return $String;
    }
    if(($Bound !== 'left') and ($Bound !== 'right')){
        trigger_error('$Bound must be "left" or "right".', E_USER_WARNING);
    }
    if($Bound === 'right'){
        $Pattern = "^.{0,{$Length}}\\b";
    }else{
        $Pattern = "^.{{$Length}}.*?\\b";
    }
    return preg_match("~{$Pattern}~", $String, $Slices) ? trim($Slices[0]) : false;
}

/**
* Alias of ChunkWordsByLength($String, $Length, 'right').
* 
* @param string $String
* @param int $Length
* @return string
*/
function ChunkWordsByLengthMax($String, $Length){
    return ChunkWordsByLength($String, $Length, 'right');
}

/**
* Alias of ChunkWordsByLength($String, $Length, 'left').
* 
* @param string $String
* @param int $Length
* @return string
*/
function ChunkWordsByLengthMin($String, $Length){
    return ChunkWordsByLength($String, $Length, 'left');
}

它使用 RegExp 并允许您将 Length 设置为最小或最大字符。它也短了很多,但我在使用时添加了错误检查。

  1. Bound 为“正确”时,它就在 Length 之前。
  2. Bound 为 'left' 时,它会在 Length 之后中断。

这样使用:

var_dump(ChunkWordsByLengthMax($String, 120));
var_dump(ChunkWordsByLengthMin($String, 120));

希望对你有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-03
    • 2011-03-09
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 2011-10-02
    • 2021-10-28
    相关资源
    最近更新 更多