简体   繁体   English

需要一种可扩展的方法来通过在PHP中使用substr()和strpos()来限制内容

[英]Need a scalable way to Limit Content by using substr() and strpos() in PHP

I am using Markdown to render a rich content on a page, using PHP. 我正在使用Markdown使用PHP在页面上呈现丰富的内容。 For the brief version, I think it would be fine to truncate the content till second paragraph, or technically, after two \\r\\n have crossed. 对于简短版本,我认为可以将内容截断到第二段,或者技术上,在两个\\r\\n之后将其截断。 So I used this code: 所以我使用了这段代码:

substr($content, 0, strpos($content, "\r\n\r\n", strpos($content, "\r\n\r\n") + 1));

Since the count of \\r\\n is hard coded, and is also calculated in a weird way, (using +1 after the first position and stuff) , is there a better way I can make a function, which says limitContent($content, $lines = 2) and passing the number of lines to the $lines parameter, as by default, it truncates to two lines? 由于\\r\\n的计数是硬编码的,并且也是以一种奇怪的方式计算的(在第一个位置和东西之后使用+1) ,是否有更好的方法可以创建一个函数,即limitContent($content, $lines = 2)并将行数传递给$lines参数,默认情况下,它会截断为两行?

My current code is: 我目前的代码是:

/**
 * Break down the content of Markdown upto 2 breaks. 
 * @param string Markdown String
 * @return string Markdown String upto 2 breaks
 */
function limitContent($content)
{
    return substr($content, 0, strpos($content, "\r\n\r\n", strpos($content, "\r\n\r\n") + 1));
}

Thanks in advance. 提前致谢。

You could use explode() for that: 您可以使用explode()

join("\r\n", array_slice(explode("\r\n\r\n", $content, $lines + 1), 0, $lines));

Or similarly, using preg_split() - to match both LF and CRLF: 或者类似地,使用preg_split() - 匹配LF和CRLF:

join("\r\n", array_slice(preg_split("/(?:\r?\n){2}/", $content, $lines), 0, $lines));

Above solutions are not very memory efficient though, because the full content after the last match is copied into the last array element. 上述解决方案的内存效率不是很高,因为最后一次匹配后的完整内容被复制到最后一个数组元素中。

You could also use strtok() as this might be more memory efficient: 您也可以使用strtok()因为这可能会提高内存效率:

$result = '';
for ($i = 0, $tok = strtok($s, "\r\n\r\n"); false !== $tok && $i < $lines; ++$i, $tok = strtok("\r\n\r\n")) {
        $result .= $t . PHP_EOL;
}

Ok, I misunderstood. 好吧,我误解了。 Is this what you want? 这是你想要的吗?

function limitContent($content, $lines=2)
{
    $tmp=explode("\r\n\r\n", $content);
    $tmp=array_slice($tmp,0,$lines);
    return implode("\r\n", $tmp);
}

[edit] And slightly better would be: [编辑]稍微好一点是:

function limitContent($content, $lines=2)
    {
        $tmp=explode("\r\n\r\n", $content, $lines+1);
        unset($tmp[$lines]);
        return implode("\r\n", $tmp);
    }

I was interessted in the performance difference between both options in Nin's answer so I started a quick check with some data I had at hand. 我对Nin的答案中两个选项之间的性能差异进行了调整,所以我开始快速检查我手头的一些数据。 I tested against 2 string: a long string with many paragraphs and one long string with 2 paragraphs. 我测试了2个字符串:一个包含许多段落的长字符串和一个包含2个段落的长字符串。

Option 2 turn out to be 14 times faster on the first string and 6% faster on the second string. Option 2在第一个字符串上的14 times faster14 times faster ,在第二个字符串上的6% faster6% faster So this has a huge advantage on the first string. 所以这对第一个字符串有很大的优势。

Moreover I turned Praveen Kumar's initial idea into a simple loop based version and tested it: 此外,我将Praveen Kumar最初的想法变成了一个简单的基于循环的版本并对其进行了测试:

function limitContent($content, $lines=2) {
    $pos = -1;
    for ($i = 0; $i < $lines; $i++) {
        $pos = strpos($content, "\r\n\r\n", $pos+1);
        if ($pos === false) return $content;
    }
    return substr($content, 0, $pos);
}

This version turned out to be another 178 times faster on the first string and another 25 times faster on the second string. 这个版本在第一个字符串上的178 times faster178 times faster ,在第二个字符串上又提高了25 times faster While these numbers might change a lot for you depending on data and php version I think it clearly shows that converting to an array and back is slow. 虽然根据数据和php版本,这些数字可能会对你有很大的改变,但我认为它清楚地表明转换为数组并返回的速度很慢。 I'd probably still use Nin's idea if performance is not a concern because it's pretty straight forward to read. 如果表现不是一个问题,我可能仍然会使用Nin的想法,因为它很容易阅读。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM