确保PHP substr在单词而不是字符上完成

确保PHP substr在单词而不是字符上完成,php,substring,Php,Substring,我知道如何使用substr函数,但这会在一个单词的中间结束一个字符串。我希望字符串在一个单词的末尾结束,我该怎么做呢?它会涉及正则表达式吗?非常感谢您的帮助 这就是我目前所拥有的。只是下一个 echo substr("$body",0,260); 干杯这可以用正则表达式完成,类似这样的东西从字符串开始到单词边界最多可以包含260个字符: $line=$body; if (preg_match('/^.{1,260}\b/s', $body, $match)) { $line=$matc

我知道如何使用substr函数,但这会在一个单词的中间结束一个字符串。我希望字符串在一个单词的末尾结束,我该怎么做呢?它会涉及正则表达式吗?非常感谢您的帮助

这就是我目前所拥有的。只是下一个

echo substr("$body",0,260);

干杯

这可以用正则表达式完成,类似这样的东西从字符串开始到单词边界最多可以包含260个字符:

$line=$body;
if (preg_match('/^.{1,260}\b/s', $body, $match))
{
    $line=$match[0];
}
或者,您可以使用该函数将$body拆分为行,然后只提取第一行。

您可以尝试以下操作:

   $s = substr($string, 0, 261);
   $result = substr($s, 0, strrpos($s, ' '));

可以这样做:从上的第260个字符中找到第一个空格,并将其用作裁剪标记:

$pos = strpos($body, ' ', 260);
if ($pos !== false) {
    echo substr($body, 0, $pos);
}
我使用这个解决方案:

$maxlength = 50;
substr($name, 0, ($spos = strpos($name, ' ', $lcount = count($name) > $maxlength ? $lcount : $maxlength)) ? $spos : $lcount );
或内联:

substr($name, 0, ($spos = strpos($name, ' ', $lcount = count($name) > 50 ? $lcount : 50)) ? $spos : $lcount );
函数子字符串($body,$maxlength){
如果(strlen($body)0)$body=substr($body,0,$rpo);
返回$body;
}
公共功能条\文本($data,$size,$lastString=”“){
$data=带标签($data);
如果(mb_strlen($data,'utf-8')>$size){
$result=mb_substr($data,0,mb_strpo($data,,$size,'utf-8'),'utf-8');
如果(mb_strlen($result,'utf-8')0){
$result.=$lastString;
}
}否则{
$result=$data;
}
返回$result;
}
将字符串传递到funtionStrip_text(“带html标记或不带html标记的长文本”,15) 然后,此函数将返回不带html标记的html字符串的前15个字符。如果字符串小于15个字符,则返回完整字符串,否则将返回带有$lastString参数字符串的15个字符

示例:

Strip_text("<p>vijayDhanasekaran</p>", 5)
Strip\u文本(“vijayDhanasekaran

”,5)
结果:维杰

Strip_text("<h1>vijayDhanasekaran<h1>",5,"***....")
Strip_文本(“vijayDhanasekaran”,5,***…)
结果:vijay***..

尝试此功能

<?php
/**
 * trims text to a space then adds ellipses if desired
 * @param string $input text to trim
 * @param int $length in characters to trim to
 * @param bool $ellipses if ellipses (...) are to be added
 * @param bool $strip_html if html tags are to be stripped
 * @param bool $strip_style if css style are to be stripped
 * @return string
 */
function trim_text($input, $length, $ellipses = true, $strip_tag = true,$strip_style = true) {
    //strip tags, if desired
    if ($strip_tag) {
        $input = strip_tags($input);
    }

    //strip tags, if desired
    if ($strip_style) {
        $input = preg_replace('/(<[^>]+) style=".*?"/i', '$1',$input);
    }

    if($length=='full')
    {

        $trimmed_text=$input;

    }
    else
    {
        //no need to trim, already shorter than trim length
        if (strlen($input) <= $length) {
        return $input;
        }

        //find last space within length
        $last_space = strrpos(substr($input, 0, $length), ' ');
        $trimmed_text = substr($input, 0, $last_space);

        //add ellipses (...)
        if ($ellipses) {
        $trimmed_text .= '...';
        }       
    }

    return $trimmed_text;
}
?>

换行并分解然后第一个数组元素就是您想要的
$wr=wordwrap($text,20':');
$strs=爆炸(“:”,$wr);
$strs[0]

这个怎么样

/**
 * @param string $text
 * @param int $limit
 * @return string
 */
public function extractUncutPhrase($text, $limit)
{
    $delimiters = [',',' '];
    $marks = ['!','?','.'];

    $phrase = substr($text, 0, $limit);
    $nextSymbol = substr($text, $limit, 1);


    // Equal to original
    if ($phrase == $text) {
        return $phrase;
    }
    // If ends with delimiter
    if (in_array($nextSymbol, $delimiters)) {
        return $phrase;
    }
    // If ends with mark
    if (in_array($nextSymbol, $marks)) {
        return $phrase.$nextSymbol;
    }

    $parts = explode(' ', $phrase);
    array_pop($parts);

    return implode(' ', $parts); // Additioanally you may add ' ...' here.
}
测试:

public function testExtractUncutPhrase()
{
    $stringUtils = new StringUtils();

    $text = 'infant ton-gue could make of both names nothing';
    $phrase = 'infant';

    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 11));
    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 12));

    $text = 'infant tongue5';
    $phrase = 'infant';

    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 13));
    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 11));
    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 7));
}

public function testExtractUncutPhraseEndsWithDelimiter()
{
    $stringUtils = new StringUtils();

    $text = 'infant tongue ';
    $phrase = 'infant tongue';

    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 13));

    $text = 'infant tongue,';
    $phrase = 'infant tongue';

    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 13));
}

public function testExtractUncutPhraseIsSentence()
{
    $stringUtils = new StringUtils();

    $text = 'infant tongue!';
    $phrase = 'infant tongue!';

    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 14));
    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 100));

    $text = 'infant tongue!';
    $phrase = 'infant tongue!';

    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 13));

    $text = 'infant tongue.';
    $phrase = 'infant tongue.';

    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 13));
}

我想他们可能已经投了反对票,因为它没有使用PHP,谁知道呢。很好用,谢谢。UTF8怎么样?我对正则表达式的使用非常糟糕。尝试使用/u修饰符来匹配UTF-8,例如,
/^.{1260}\b/su
好吧,即使它少于260个字符,它仍然会在单词边界上中断,因此生成有效的结果。但是你可以在尝试正则表达式之前检查字符串的长度。这似乎很有效。需要注意的一个边缘情况是,如果前260个字符中根本没有空格字符,它只返回整个字符串。如果这是一个问题,您可以添加类似于
$line=mb_substr($line,0260)强制在该长度上中断。时尚的解决方案,但是UTF-8呢?是的,但是strpos不会混淆,因为现在260实际上是130个字符?如果文本短于260个字符,使用此选项可以生成strpos警告。这有很多问题。如前所述,如果字符串长度小于260个字符,或者不包含任何空格,则会失败。它也没有将字符串限制为260个字符,而是在260个字符后的空格处打断字符串,这通常不是您想要的。如果单词break是一种不同类型的空白,例如制表符或换行符,那么它也不起作用。它也不是多字节兼容的。Paul Dixon的preg_match()解决方案是一个更好的解决方案。@zed的答案纠正了此解决方案关于超出字符限制的问题。更多的上下文或解释可能会有用:它是如何工作的,为什么使用此方法,等等。当您输入utf-8字体(例如“泰米尔”)时,您可以获得不带无关字符的子字符串。请尝试此链接,可能会帮助您。。。在一个不相关的问题上,为什么要使用
“$body”
,而不是简单地使用
$body
?这是最好的答案!与@achshar解决方案相反,此解决方案允许保留整个单词,同时不超过单词限制。关键是使用
strrpos
函数查找前261个字符中的最后一个空格,返回该位置,然后使用
substr
在该位置切片字符串。请记住在
if
语句中包含所有这些,以便仅在文本大于260个字符时应用函数。我认为这是最干净的解决方案,即使是一行的
echo爆炸(“| |”,wordwrap($text,20,“| |”)[0]
Strip_text("<h1>vijayDhanasekaran<h1>",5,"***....")
<?php
/**
 * trims text to a space then adds ellipses if desired
 * @param string $input text to trim
 * @param int $length in characters to trim to
 * @param bool $ellipses if ellipses (...) are to be added
 * @param bool $strip_html if html tags are to be stripped
 * @param bool $strip_style if css style are to be stripped
 * @return string
 */
function trim_text($input, $length, $ellipses = true, $strip_tag = true,$strip_style = true) {
    //strip tags, if desired
    if ($strip_tag) {
        $input = strip_tags($input);
    }

    //strip tags, if desired
    if ($strip_style) {
        $input = preg_replace('/(<[^>]+) style=".*?"/i', '$1',$input);
    }

    if($length=='full')
    {

        $trimmed_text=$input;

    }
    else
    {
        //no need to trim, already shorter than trim length
        if (strlen($input) <= $length) {
        return $input;
        }

        //find last space within length
        $last_space = strrpos(substr($input, 0, $length), ' ');
        $trimmed_text = substr($input, 0, $last_space);

        //add ellipses (...)
        if ($ellipses) {
        $trimmed_text .= '...';
        }       
    }

    return $trimmed_text;
}
?>
/**
 * @param string $text
 * @param int $limit
 * @return string
 */
public function extractUncutPhrase($text, $limit)
{
    $delimiters = [',',' '];
    $marks = ['!','?','.'];

    $phrase = substr($text, 0, $limit);
    $nextSymbol = substr($text, $limit, 1);


    // Equal to original
    if ($phrase == $text) {
        return $phrase;
    }
    // If ends with delimiter
    if (in_array($nextSymbol, $delimiters)) {
        return $phrase;
    }
    // If ends with mark
    if (in_array($nextSymbol, $marks)) {
        return $phrase.$nextSymbol;
    }

    $parts = explode(' ', $phrase);
    array_pop($parts);

    return implode(' ', $parts); // Additioanally you may add ' ...' here.
}
public function testExtractUncutPhrase()
{
    $stringUtils = new StringUtils();

    $text = 'infant ton-gue could make of both names nothing';
    $phrase = 'infant';

    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 11));
    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 12));

    $text = 'infant tongue5';
    $phrase = 'infant';

    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 13));
    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 11));
    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 7));
}

public function testExtractUncutPhraseEndsWithDelimiter()
{
    $stringUtils = new StringUtils();

    $text = 'infant tongue ';
    $phrase = 'infant tongue';

    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 13));

    $text = 'infant tongue,';
    $phrase = 'infant tongue';

    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 13));
}

public function testExtractUncutPhraseIsSentence()
{
    $stringUtils = new StringUtils();

    $text = 'infant tongue!';
    $phrase = 'infant tongue!';

    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 14));
    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 100));

    $text = 'infant tongue!';
    $phrase = 'infant tongue!';

    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 13));

    $text = 'infant tongue.';
    $phrase = 'infant tongue.';

    $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 13));
}