2012-01-28 3 views
2

내부 링크를 절단하지 않고 나는이 같은 문자열이있어 :단축 텍스트는 짹짹 같은

I love @kevinrose 's new website <a href="http://kevinrose.com">Link</a> 

을 그리고이 기능이 있습니다

function short($string, $max = 255) { 
    if (strlen($string) >= $max) { 
     $string = mb_substr($string, 0, $max - 5, 'utf-8') . '...'; 
    } return $string; 
} 

나는 50에서 화면을 잘라 경우, 궁극적으로 다음과 같은 결과를 가져옵니다.

I love @kevinrose 's new website <a href="http://kevinr... 

물론 html을 삭제합니다.

HTML을 손상시키지 않고 href 태그를 잘라내지 않는 쉬운 방법이 있습니까?

나는 물론 내 태그를 유지해야합니다.

+0

가능한 중복 [PHP : HTML을 잘라 내기 태그를 무시 (http://stackoverflow.com/questions/1193500/php-truncate-html-ignoring-tags) – user

답변

5

는 PHP에서 이것을 볼 주셔서 감사합니다 : 문자열을 잘라 내기 HTML 태그와 전체 단어를 유지하면서 - 앨런 위플 ->http://alanwhipple.com/2011/05/25/php-truncate-string-preserving-html-tags-words/

<?php 
/** 
* truncateHtml can truncate a string up to a number of characters while preserving whole words and HTML tags 
* 
* @param string $text String to truncate. 
* @param integer $length Length of returned string, including ellipsis. 
* @param string $ending Ending to be appended to the trimmed string. 
* @param boolean $exact If false, $text will not be cut mid-word 
* @param boolean $considerHtml If true, HTML tags would be handled correctly 
* 
* @return string Trimmed string. 
*/ 
function truncateHtml($text, $length = 100, $ending = '...', $exact = false, $considerHtml = true) { 
    if ($considerHtml) { 
     // if the plain text is shorter than the maximum length, return the whole text 
     if (strlen(preg_replace('/<.*?>/', '', $text)) <= $length) { 
      return $text; 
     } 
     // splits all html-tags to scanable lines 
     preg_match_all('/(<.+?>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER); 
     $total_length = strlen($ending); 
     $open_tags = array(); 
     $truncate = ''; 
     foreach ($lines as $line_matchings) { 
      // if there is any html-tag in this line, handle it and add it (uncounted) to the output 
      if (!empty($line_matchings[1])) { 
       // if it's an "empty element" with or without xhtml-conform closing slash 
       if (preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1])) { 
        // do nothing 
       // if tag is a closing tag 
       } else if (preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings)) { 
        // delete tag from $open_tags list 
        $pos = array_search($tag_matchings[1], $open_tags); 
        if ($pos !== false) { 
        unset($open_tags[$pos]); 
        } 
       // if tag is an opening tag 
       } else if (preg_match('/^<\s*([^\s>!]+).*?>$/s', $line_matchings[1], $tag_matchings)) { 
        // add tag to the beginning of $open_tags list 
        array_unshift($open_tags, strtolower($tag_matchings[1])); 
       } 
       // add html-tag to $truncate'd text 
       $truncate .= $line_matchings[1]; 
      } 
      // calculate the length of the plain text part of the line; handle entities as one character 
      $content_length = strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', ' ', $line_matchings[2])); 
      if ($total_length+$content_length> $length) { 
       // the number of characters which are left 
       $left = $length - $total_length; 
       $entities_length = 0; 
       // search for html entities 
       if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', $line_matchings[2], $entities, PREG_OFFSET_CAPTURE)) { 
        // calculate the real length of all entities in the legal range 
        foreach ($entities[0] as $entity) { 
         if ($entity[1]+1-$entities_length <= $left) { 
          $left--; 
          $entities_length += strlen($entity[0]); 
         } else { 
          // no more characters left 
          break; 
         } 
        } 
       } 
       $truncate .= substr($line_matchings[2], 0, $left+$entities_length); 
       // maximum lenght is reached, so get off the loop 
       break; 
      } else { 
       $truncate .= $line_matchings[2]; 
       $total_length += $content_length; 
      } 
      // if the maximum length is reached, get off the loop 
      if($total_length>= $length) { 
       break; 
      } 
     } 
    } else { 
     if (strlen($text) <= $length) { 
      return $text; 
     } else { 
      $truncate = substr($text, 0, $length - strlen($ending)); 
     } 
    } 
    // if the words shouldn't be cut in the middle... 
    if (!$exact) { 
     // ...search the last occurance of a space... 
     $spacepos = strrpos($truncate, ' '); 
     if (isset($spacepos)) { 
      // ...and cut the text in this position 
      $truncate = substr($truncate, 0, $spacepos); 
     } 
    } 
    // add the defined ending to the text 
    $truncate .= $ending; 
    if($considerHtml) { 
     // close all unclosed html-tags 
     foreach ($open_tags as $tag) { 
      $truncate .= '</' . $tag . '>'; 
     } 
    } 
    return $truncate; 
} 

?> 

여기를 참조

+0

감사합니다! 잘 작동합니다! – xtrimsky

+0

이것은 매우 훌륭합니다. 나는이 문제에 질려했다. 이 코드는 완벽하게 작동합니다. – Pramod

1

다음은 약간 짧은 방법입니다. DOM 트리를 걷지는 않지만 거의 모든 상황에서 작동합니다.

이 메서드는 먼저 모든 HTML 태그를 내용에서 제거하므로 HTML 태그도 문자열 길이만큼 계산되지 않습니다. 그런 다음 문자열을 잘릴 필요가 있으면 문자열을 자르고 모든 html 태그를 다시 삽입합니다. 의

<?php 
function short($string, $max = 255) { 
    preg_match_all('/<[^>]+>/', $string, $tags); // Save tag information for later 
    $stripped = preg_replace('/<[^>]+>/', '', $string); // Strip html tags 

    // Truncate the string if needed 
    if (strlen($stripped) > $max) { 
     $truncated = mb_substr($stripped, 0, $max, 'utf-8'); 

     // Insert html tags, if any 
     if (sizeof($tags) > 0) { 
      $pos = 0; 
      foreach ($tags[0] as $tag) { 
       $pos += strpos($string, $tag); // Get the position the tag should be inserted at 
       $string = substr($string, $pos); // Shift to avoid issues with duplicate tags 
       $truncated = substr_replace($truncated, $tag, $pos, 0); // Insert the tag 
      } 
     } 

     $string = $truncated . '&hellip;'; 
    } 

    return $string; 
} 

echo short('I love @kevinrose\'s new website <a href="http://kevinrose.com">Link</a>. Here is a bit of additional text after the link.<a></a>', 50); 
+0

더 많은 HTML 태그와 함께 작동하지 않습니다. – Francesco