2012-06-23 3 views
0

Я работаю в PHP и хочу создать функцию, которая при заданном тексте произвольной длины и высоты возвращает ограниченную версию того же текста с максимальным количеством символов 500 и 10 линий.Выполнение предварительного просмотра длинного текста

Это то, что я до сих пор:

function preview($str) 
{ 
    $partialPreview = explode("\n", substr($str, 0, 500)); 
    $partialPreviewHeight = count($partialPreview); 
    $finalPreview = ""; 

    // if it has more than 10 lines 
    if ($partialPreviewHeight > 10) { 
     for ($i = 0; $i < 10; $i++) { 
      $finalPreview .= $partialPreview[$i]; 
     } 
    } else { 
     $finalPreview = substr($str, 0, 500); 
    } 

    return $finalPreview; 
} 

У меня есть два вопроса:

  • Пользуется \n присущий обнаружить новую линию кормов? Я знаю, что некоторые системы используют \n, другие \r\n и другие \r, но \n - самые общие.
  • Иногда, если есть объект HTML, такой как &quot; (кавычка) на , он оставлен как &quot, и поэтому он недействителен HTML. Как я могу предотвратить это?

ответ

0

Используется ли \ n для обнаружения новых линий? Я знаю, что некоторые системы используют \ n, другие \ r \ n и другие \ r, но \ n является наиболее распространенным.

Это зависит от того, откуда поступают данные. Различные операционные системы имеют разные разрывы строк.

Windows использует \r\n, * nix (включая Mac OS) используется \n, (очень) старый macs б/у \r. Если данные поступают из Интернета (например, в textarea), он будет (/ должен) всегда быть \r\n. Потому что это то, что the spec заявляет user agents should do.

Иногда, если есть HTML объект как " (кавычки) в конце концов, он оставил в & Quot, и, следовательно, это не действует HTML. Как я могу это предотвратить?

Перед тем, как разрезать текст, вы можете преобразовать объекты html в обычный текст. Используя htmlspecialchars_decode() или html_entity_decode в зависимости от ваших потребностей. Теперь у вас не будет проблемы с разбиением сущностей (не забудьте снова закодировать его, если это необходимо).

Другой вариант заключается в том, чтобы сломать текст только на символы пробелов, а не на жесткий символ. Таким образом, у вас будут только целые слова в вашем «резюме».

Я создал класс, который должен иметь дело с большинством проблем. Как я уже говорил, когда данные поступают из текстового поля всегда будет \r\n, но чтобы быть в состоянии разобрать другие переносы строк я придумал что-то вроде следующего (непроверенные):

class Preview 
{ 
    protected $maxCharacters; 
    protected $maxLines; 
    protected $encoding; 
    protected $lineBreaks; 

    public function __construct($maxCharacters = 500, $maxLines = 10, $encoding = 'UTF-8', array $lineBreaks = array("\r\n", "\r", "\n")) 
    { 
     $this->maxCharacters = $maxCharacters; 
     $this->maxLines = $maxLines; 
     $this->encoding = $encoding; 
     $this->lineBreaks = $lineBreaks; 
    } 

    public function makePreview($text) 
    { 
     $text = $this->normalizeLinebreaks($text); 

     // this prevents the breaking of the &quote; etc 
     $text = html_entity_decode($text, ENT_QUOTES, $this->encoding); 

     $text = $this->limitLines($text); 

     if (mb_strlen($text, $this->encoding) > $this->maxCharacters) { 
      $text = $this->limitCharacters($text); 
     } 

     return html_entity_decode($text, ENT_QUOTES, $this->encoding); 
    } 

    protected function normalizeLinebreaks($text) 
    { 
     return str_replace($lineBreaks, "\n", $text); 
    } 

    protected function limitLines($text) 
    { 
     $lines = explode("\n", $text); 
     $limitedLines = array_slice($lines, 0, $this->maxLines); 

     return implode("\n", $limitedLines); 
    } 

    protected function limitCharacters($text) 
    { 
     return substr($text, 0, $this->maxCharacters); 
    } 
} 

$preview = new Preview(); 
echo $preview->makePreview('Some text which will be turned into a preview.'); 
+0

Спасибо, очень полный ответ и большое спасибо за класс Preview, он отлично работает! – federicot

1

Сначала заменить <br /> метки с <br />\n и </p><p> или </div><div> с </p>\n<p> и </div>\n<div> соответственно.

Затем используйте функцию PHP для strip tags, которая должна давать хороший простой текст с символами новой строки во всех местах, где должна стоять новая строка.

Затем вы можете заменить \r\n на \n для обеспечения согласованности. И только после этого вы можете извлечь желаемую длину текста.

Возможно, вы захотите использовать word wrapping, чтобы достичь 10-мя целей. Для использования переносов слов вам необходимо определить количество символов в строке, а перенос слов - не тормозить середину слова.

Вы можете использовать html_entity_decode перед использованием wordwrap как предложено @PeeHaa.