2011-09-09 3 views
0

저는 현재 페이스 북과 트위터 피드를 가져 오는 클래스를 작성하고 웹 사이트에 표시하기 위해 이들을 하나로 결합합니다.올바르게 substr PHP가있는 'a'요소를 포함하는 문자열

그러나 a 요소로 인해 입력 된 텍스트의 출력 제한으로 인해 하나의 문제가 발생하여 간단한 substr 기능 후에 닫히지 않게됩니다.

'Check out our site at <a href="http://site.com/">site.com</a>' 

내가 50 자이를 제한하려면 :

그래서 내가이 캐릭터를 상상한다. 단순히 substr($input,0,50)을한다면 나는 다음으로 끝날 것입니다 : 링크로 내 웹 사이트의 나머지 부분을 켜집니다

'Check out our site at <a href="http://site.com/">s' 

닫히지 않은 a 요소.

어쩌면 DOMDocument를 사용하여 임시로 전체 URL을 <a></a> 사이의 부분으로 바꿀 수 있다고 생각했습니다. 빼기를 수행 한 다음 링크를 다시 적용하십시오.

그러나이 방법을 알아낼 수 없으며 다른 문제/선택 사항을 남겨 둡니다. 링크를 일시적으로 바꿀 수 있다고 가정하면 - 빼기 후에 링크가 절반으로 끝납니다 : 그것은 [[id]] 같은로 교체 아마도 더 나은 그냥 스크립트는 텍스트가 얼마나 오래 기억 그래서

'Check out our site at sit' 

는 그런 다음, 링크를 다시 적용하기 어려울 것이다.

어쨌든, 저와 함께 도울 수있는 사람이 있습니까?

편집 다른 모든 항목에는 strip_tags이므로 a 태그에만 적용됩니다.

+0

볼 innerText와 : http://www.quirksmode.org/dom/w3c_html.html#t04 – Dor

답변

0

내가 어쩌면 몇 가지 개선을 사용할 수, 결국 내 자신의 기능을 쓴하지만 작동 :

private function substr_html($input,$limit){ 

    $original = $input; 

    if(strlen($input) <= $limit) 
     return $input; 

    $pattern = '#<a\s+.*?href=[\'"]([^\'"]+)[\'"]\s*?.*?>((?:(?!</a>).)*)</a>#i'; 

    // Match all 'a' elements 
    preg_match_all($pattern,$input,$matches); 

    // If no links were found, perform a simple substr() 
    if(count($matches[0]) == 0) 
     return substr($input,0,$limit).'...'; 

    $uni  = sha1(uniqid());  

    preg_replace($pattern,$uni,$input); 

    $input = explode($uni,$input); 
    $tmp = $output = ''; 

    // Go through the splitted input   
    foreach($input as $i){ 

     if(strlen($tmp.$i) < $limit){ 

      // If we can fit the next text value without reaching the limit, do it 
      $tmp .= $i; 
      $output .= $i; 

     }else{ 

      // Add whatever we can fit from the last text value and break the loop 
      $diff = abs($limit - strlen($tmp)); 
      $output .= substr($i,0,$diff); 
      break; 

     } 

     if(strlen($tmp) < $limit){ // Do we still have room before we reach the limit? 

      $nextlink = array_shift($matches[1]); 
      $nexttext = array_shift($matches[2]); 

      if(strip_tags($nexttext,$this->allowed_tags) != '') 
       if(strlen($tmp.$nexttext) < $limit){   

        // Add the next link if it fits 
        $tmp .= $nexttext; 
        $output .= '<a href="'.$nextlink.'" target="_blank">'.$nexttext.'</a>'; 

       }else{ 

        // Add whatever we can fit from the last link and break the loop 
        $diff = abs($limit - strlen($tmp)); 
        $output .= '<a href="'.$nextlink.'" target="_blank">'.substr($nexttext,0,$diff).'</a>'; 
        break; 

       } 

     } 

    } 

    // Trim string and remove linebreaks 
    $output = trim(preg_replace('/((<br>|<br\/>|<br \/>){1,})/'," ",$output)); 

    return $output.(strip_tags($original) != strip_tags($output) ? '...' : ''); 

} 
1

이 스 니펫은 php.net/substr에서 유용합니다.

예 :

echo substrws("Check out our site at <a href=\"http://site.com/\">site.com</a>. It's really <strong>nice</strong>", 50); 

수익률 :

Check out our site at <a href="http://site.com/">site.com</a>.

코드 :

/** 
* word-sensitive substring function with html tags awareness 
* @param text The text to cut 
* @param len The maximum length of the cut string 
* @returns string 
**/ 
function substrws($text, $len=180) { 

    if((strlen($text) > $len)) { 

     $whitespaceposition = strpos($text," ",$len)-1; 

     if($whitespaceposition > 0) 
      $text = substr($text, 0, ($whitespaceposition+1)); 

     // close unclosed html tags 
     if(preg_match_all("|<([a-zA-Z]+)>|",$text,$aBuffer)) { 

      if(!empty($aBuffer[1])) { 

       preg_match_all("|</([a-zA-Z]+)>|",$text,$aBuffer2); 

       if(count($aBuffer[1]) != count($aBuffer2[1])) { 

        foreach($aBuffer[1] as $index => $tag) { 

         if(empty($aBuffer2[1][$index]) || $aBuffer2[1][$index] != $tag) 
          $text .= '</'.$tag.'>'; 
        } 
       } 
      } 
     } 
    } 

    return $text; 
} 
+0

몇 가지 테스트를 한 후 실제로 다양한 수준에서 작동하기 시작했습니다. 그래서 나는 더 많은 것들을 시도하고 마침내 내 자신의 코드를 작성할 수 있습니다 (어쩌면 개선 될 수 있지만 완벽하게 작동합니다). – Kokos

0

또 다른 해결책은 strip_tags() 것 -이 같은 PHP의 기능 :

<?php 
$text = '<p>Check out our site at </p><!-- other html stuff anywhere--> <a href="http://site.com/">site.com</a>'; 
echo strip_tags($text); 
echo "\n"; 

// juts allow <p> and <a> 
echo strip_tags($text, '<p><a>'); 
?>