2012-04-25 9 views
1

完全な文字列を切り捨てるときにSEARCH TERMの前後の文字数を厳密にカウントする検索結果があります。残念なことに、これにより出力は途中の単語を切り捨てます。 (...前後の楕円でカウントする)PHP - 単語を切り捨てずに出力を表示

私は、検索結果を空白でのみ、単語の真ん中で完全な文字列を切り詰めようとしています。ここで

機能です:ちょうど文字列出力、楕円「を探す」という機能を使って、文字列によるスクリプトべきループを表示する前に...

private function _highlight_results(){ 

    $GLOBALS['_SEARCH_SUMMARY_LENGTH'] = 24; 

    foreach($this->results as $url => &$this_result){ 
     if(!$this_result['url_display'] && $this_result['url']){ 
      $this_result['url_display'] = $this_result['url']; 
     } 
     foreach($this_result['search_term'] as $search_term){ 
      $search_term = preg_quote($search_term,'/'); 

      foreach(array('title','summary','url_display') as $highlight_item){ 
       if($this_result[$highlight_item] && preg_match('/'.$search_term.'/i',$this_result[$highlight_item])){ 
        if($highlight_item != 'url_display' && strlen($this_result[$highlight_item]) > $GLOBALS['_SEARCH_SUMMARY_LENGTH']){ 
         $boobs = ceil(($GLOBALS['_SEARCH_SUMMARY_LENGTH']-strlen($this->_search_term))/2); 
         preg_match('/(.{0,'.$boobs.'})('.$search_term.')(.{0,'.$boobs.'})/i',$this_result[$highlight_item],$matches); 
         // want to even out the strings a bit so if highlighted term is at end of string, put more characters infront. 
         $before_limit = $after_limit = ($boobs - 2); 
         if(strlen($matches[1])>=$before_limit && strlen($matches[3])>=$after_limit){ 
          // leave limit alone. 
         }else if(strlen($matches[1])<$before_limit){ 
          $after_limit += $before_limit - strlen($matches[1]); 
          $before_limit = strlen($matches[1]); 
          preg_match('/(.{0,'.($before_limit+2).'})('.$search_term.')(.{0,'.($after_limit+2).'})/i',$this_result[$highlight_item],$matches); 
         }else if(strlen($matches[3])<$after_limit){ 
          $before_limit += $after_limit - strlen($matches[3]); 
          $after_limit = strlen($matches[3]); 
          preg_match('/(.{0,'.($before_limit+2).'})('.$search_term.')(.{0,'.($after_limit+2).'})/i',$this_result[$highlight_item],$matches); 
         } 
         $this_result[$highlight_item] = (strlen($matches[1])>$before_limit) ? '...'.substr($matches[1],-$before_limit) : $matches[1]; 
         $this_result[$highlight_item] .= $matches[2]; 
         $this_result[$highlight_item] .= (strlen($matches[3])>$after_limit) ? substr($matches[3],0,$after_limit).'...' : $matches[3]; 

        } 

       }else if(strlen($this_result[$highlight_item]) > $GLOBALS['_SEARCH_SUMMARY_LENGTH']){ 
        $this_result[$highlight_item] = substr($this_result[$highlight_item],0,$GLOBALS['_SEARCH_SUMMARY_LENGTH']).'...'; 
       } 
      } 
     } 

     foreach($this_result['search_term'] as $search_term){ 
      $search_term = preg_quote($search_term,'/'); 

      foreach(array('title','summary','url_display') as $highlight_item){ 
       $this_result[$highlight_item] = preg_replace('/'.$search_term.'/i','<span id="phpsearch_resultHighlight">$0</span>',$this_result[$highlight_item]); 
      } 
     } 
    } 
} 

は、ここで私が考えていたものだ と直後の文字を返し、その後にAFTERという文字を削除し、空白が見つかるまでループを続けます。次に、次のループは文字を探し、次に楕円を探して文字を削除し、楕円の前に空白が見つかるまでループを続けます。私はあなたが私は上記のものから探しているもののアイデアを得ることができると思い

WHILE (not the end of the string) { 
// NOT SURE IF I NEED A FOREACH LOOP HERE TO CHECK EACH CHAR 
    IF (^ ('...' and an immediate char are found)) { 
      delete chars until a white space is found; 

      // if '...' is deleted along with the chars, then put the '...' back in: 
      //string .= '...' . string; 
    } 
    IF ($ (a char and an immediate '...' are found)) { 
      delete chars until a white space is found; 

      // if '...' is deleted along with the chars, then put the '...' back in: 
      //string .= string . '...'; 
    } 
} 
PRINT string; 

:ここ

は、上記の私の記述のいくつかの非常に悲しい擬似コードです。私はwordwrap()を研究し、テストしましたが、答えはまだ見つかりませんでした。

+0

このサイトの正規表現でwordwrapを検索することをお勧めします。類似しているので、いくつかのポインタが必要です。 – hakre

+0

このリンクを試してみると... http://stackoverflow.com/a/26098951/3944217 – edCoder

答えて

0

ここでは、うまくいくはずであり、かなりパフォーマンスが良い方法もあります。唯一の欠点は、それが現れたときにスペース上の単語だけを壊すことであり、strspnを補完する機能がないので(これは簡単に記述でき、この解決法を拡張するために使用することができる)strrspn関数がないため、

function display_short($str, $limit, $ellipsis = '...') { 
    // if all of it fits there's nothing to do 
    if (strlen($str) <= $limit) { 
     return $str; 
    } 

    // $ellipsis will count towards $limit 
    $limit -= strlen($ellipsis); 

    // find the last space ("word boundary") 
    $pos = strrpos($str, ' ', $limit - strlen($str)); 

    // if none found, prefer breaking into the middle of 
    // "the" word instead of just giving up 
    if ($pos === false) { 
     $pos = $limit; 
    } 

    return substr($str, 0, $pos).$ellipsis; 
} 

試験有する:

$string = "the quick brown fox jumps over the lazy dog"; 
for($limit = 10; $limit <= strlen($string); $limit += 10) { 
    print_r(display_short($string, $limit)); 
} 

See it in action

+0

この関数を試してみましたが、このエラーが表示されます:未定義の関数display_short()を呼び出すと、どのような考えですか?この時点で – mar2195

+0

は、私がこれを処理する最も簡単な方法は、このような正規表現何かを誰かに聞いていると思う: FOREACH CHAR { \tにpreg_replace( FIND -then-文字列の先頭から 検索「...」 - then- CHARは空白されていない場合は、CHARをDELETE(またはホワイトスペースを見つけるために動く?)CHARはWHITE SPACEされている場合は、 を破る を-then-) } とENDINGため、別にpreg_replace」... ' – mar2195

+0

@ user1355539:Ideoneのライブサンプルとコードを比較し、どこが間違っているのかを簡単に調べることができると思います。それは難しいことではありません。 :) – Jon

関連する問題