Как обрезать строку до первых n слов в PHP

#php #html #truncate

#php #HTML #обрезать

Вопрос:

Я хотел бы обрезать очень длинную строку, отформатированную с помощью html-элементов.

Мне нужны первые 500 слов (каким-то образом я должен избегать html-тегов <p> , <br> пока моя функция усекает строку), но в результате я должен сохранить / использовать эти html-элементы, потому что результат также должен быть отформатирован html-тегами, такими как «оригинальный весь» текст.

Какой наилучший способ обрезать мою строку?

Пример:

Исходный текст

 > <p><a href="/t/the-huffington-post">The Huffington Post</a> (via <a
> href="/t/daily-mail">Daily Mail</a>) is reporting that <a
> href="/t/misty">Misty</a> has been returned to a high kill shelter for
> farting too much! She appeared on Greenville County Pet Rescue’s
> “urgent” list, which means if she doesn’t get readopted, she will be
> euthanized!</p>
  

Мне нужны первые n слов (n = 10)

 >  <p><a href="/t/the-huffington-post">The Huffington Post</a> (via <a
> href="/t/daily-mail">Daily Mail</a>) is reporting that.. </p>
  

Комментарии:

1. Можете ли вы пояснить, приведя пример строки и пример конечного результата. Пример до и после

2. Что вы используете для выполнения усечения, javascript, PHP или какой язык?

3. @jtorrescr Заголовок и теги говорят PHP

4. Может быть, попробовать эту функцию: php.net/manual/en/function.str-word-count.php#73577

5. Привет, Надь. Как вы справились с ответами ниже? Здесь довольно обычно голосовать, отвечать на ответы или принимать (отмечать) ответы, чтобы люди ниже знали, была ли их работа полезной для вас.

Ответ №1:

Методом грубой силы было бы просто разбить все элементы на пробелы, а затем выполнить итерацию по ним. Вы учитываете только элементы, не содержащие тегов, до максимума, в то время как теги, тем не менее, выводите. Что-то вроде этих строк:

 $string = "your string here";
$output = "";
$count = 0;
$max = 10;
$tokens = preg_split('/ /', $string);
foreach ($tokens as $token)
{
  if (preg_match('/<.*?>/', $token)) {
    $output .= "$token ";
  } else if ($count < $max) {
    $output .= "$token ";
    $count  = 1;
  }
}
print $output;
  

Ответ №2:

Вы могли бы найти что-то подобное, немного погуглив.

   // Original PHP code by Chirp Internet: www.chirp.com.au
  // Please acknowledge use of this code by including this header.

  function restoreTags($input)
  {
    $opened = array();

    // loop through opened and closed tags in order
    if(preg_match_all("/<(/?[a-z] )>?/i", $input, $matches)) {
      foreach($matches[1] as $tag) {
        if(preg_match("/^[a-z] $/i", $tag, $regs)) {
          // a tag has been opened
          if(strtolower($regs[0]) != 'br') $opened[] = $regs[0];
        } elseif(preg_match("/^/([a-z] )$/i", $tag, $regs)) {
          // a tag has been closed
          unset($opened[array_pop(array_keys($opened, $regs[1]))]);
        }
      }
    }

    // close tags that are still open
    if($opened) {
      $tagstoclose = array_reverse($opened);
      foreach($tagstoclose as $tag) $input .= "</$tag>";
    }

    return $input;
  }
  

Когда вы объединяете это с другой функцией, упомянутой в статье:

   function truncateWords($input, $numwords, $padding="")
  {
    $output = strtok($input, " n");
    while(--$numwords > 0) $output .= " " . strtok(" n");
    if($output != $input) $output .= $padding;
    return $output;
  }
  

Тогда вы можете просто достичь того, что ищете, выполнив это:

 $originalText = '...'; // some original text in HTML format
$output = truncateWords($originalText, 500); // This truncates to 500 words (ish...)
$output = restoreTags($output); // This fixes any open tags