5

多分あなたたちは助けることができます:

$bio という変数があり、バイオ データが含まれています。

$bio = "Hello, I am John, I'm 25, I like fast cars and boats. I work as a blogger and I'm way cooler then the author of the question";

関数のセットを使用して $bio を検索し、特定の単語を検索します。「author」と言って、その単語の周りにスパン クラスを追加すると、次のようになります。

$bio = "Hello, I am John, I'm 25, I like fast cars and boats. I work as a blogger and I'm way cooler then the <span class=\"highlight\">author</span> of the question";

関数を使用して、テキストを 85 文字に制限します。

$bio = limit_text($bio,85);

問題は、$bioの「author」という単語の前に 80 文字を超える文字がある場合です。が適用されると、強調表示された単語 author が表示されません。limit_text()

私が必要としているのは、 limit_text() 関数が正常に機能し、span クラスのハイライトを含むすべての単語を最後に追加することです。このようなもの:

*"This is the limited text to 85 chars, but there are no words with the span class highlight so I am putting to be continued ... **author**, **author2** (and all the other words that have a span class highlight around them separate by comma "*

私の言いたいことを理解していただければ幸いです。そうでない場合は、コメントしてください。より良い説明を試みます。

これが私のlimit_text()機能です:

function limit_text($text, $length){ // Limit Text
        if(strlen($text) > $length) {
        $stringCut = substr($text, 0, $length);
        $text = substr($stringCut, 0, strrpos($stringCut, ' '));
        }
        return $text;
    }

更新

$xturnons = str_replace(",", ", ", $xturnons);
$xbio = str_replace(",", ", ", $xbio);

$xbio = customHighlights($xbio,$toHighlight); 
$xturnons = customHighlights($xturnons,$toHighlight);

$xbio = limit_text($xbio,85);
$xturnons = limit_text($xturnons,85);

customHighlights強調表示されたスパン クラスを追加する関数:

function addRegEx($word){ // Highlight Words
        return "/" . $word . '[^ ,\,,.,?,\.]*/i';
    }
    function highlight($word){
        return "<span class='highlighted'>".$word[0]."</span>";
    }
    function customHighlights($searchString,$toHighlight){
        $searchFor = array_map('addRegEx',$toHighlight);
        $result = preg_replace_callback($searchFor,'highlight',$searchString);
        return $result;
    }
4

3 に答える 3

4

関数へのこの変更limit_textは、テキストを取得し、指定されたよりも長い場合はカットします$length。a を渡す$needleと、最初に出現したものを検索し、それで文を終了します。

また、テキストが実際の長さよりも前に切り取られた場合、文字数$additionの制限を維持したままテキストが追加され$lengthます。

以下に指定されたものに基づいて、使用法とサンプル出力を含めました。

<?php
/**
*   $text - The text to cut from
*   $length - The amount of characters that should be returned
*   $needle - If needle is given and found in the text, and it is 
*             at least $length far from the start of the string - it will end the sentence with it.
*   $addition - If the sentence was cut in the middle, will add it to the end of it.
**/
function limit_text($text, $length, $needle="", $addition="...") { 
    if(strlen($text) > $length) {
        $length -= strlen($addition);

        $start = 0;
        $trimLast = true;
        if (!empty($needle)) {
            $needleStart = strpos($text, $needle);

            if ($needleStart > $length) {
                $length -= strlen($needle);
                $start = $needleStart + strlen($needle) - $length;
                $trimLast = false;
            }
        }

        $stringCut = substr($text, max(0, $start), $length);
        if ($start > 0) {
            $stringCut = substr($stringCut, strpos($stringCut, ' ')+1);
        }
        if ($trimLast) {
            $lastWhitespace = strrpos($stringCut, ' ');
            $stringCut = substr($stringCut, 0, $lastWhitespace);
        }

        // split into words (so we won't replace words that contain it in the middle)
        // and wrap $needle with <span class="highlighted"></span>
        if (!empty($needle)) {
            $words = explode(" ", $stringCut);
            $needles = array_keys($words, $needle);
            foreach ($needles as $needleKey) {
                $words[$needleKey] = "<span class=\"highlighted\">$needle</span>";
            }

            $stringCut = implode(" ", $words);
        }
        $text = $stringCut.$addition;
    }
    return $text;
}

$bio = "Hello, I am John, I'm 25, I like fast cars and boats. I work as a blogger and I'm way cooler then the author of the question";
$text = limit_text($bio, 85, "author");
var_dump($text);

出力:

string (111) "fast cars and boats. I work as a blogger and I'm way cooler then the <span class="highlighted">author</span>..."
于 2012-06-28T01:15:25.003 に答える
2

まず、文字列を短くして単語を分割しないようにする必要があります。<span class="highlight">次に、短縮された文字列の末尾にすべてのトークンを追加する必要があります。これが私が思いついたものです(約8行で!):

function limit_text($text, $length){
    if( strlen( $text) < $length) {
        return $text;
    }

    // Truncate the string without breaking words
    list( $wrapped) = explode("\n", wordwrap( $text, $length));

    // Get the span of text occurring after the wrapped string
    $remainder = substr( $text, strlen( $wrapped));

    // Add the "to be continued" to $wrapped
    $wrapped .= ' to be continued ... ';

    // Now, grab all of the <span class="highlight"></span> tags in the $remainder
    preg_match_all( '#<span class="highlight">[^<]+</span>#i', $remainder, $matches);

    // Add the <span> tags to the end of the string, separated by a comma, if present
    $wrapped .= implode( ', ', $matches[0]);

    return $wrapped;
}

さて、元のテストで:

$bio = "Hello, I am John, I'm 25, I like fast cars and boats. I work as a blogger and I'm way cooler then the <span class=\"highlight\">author</span> of the question";
$bio = limit_text( $bio,85);
var_dump( htmlentities( $bio));

これは出力します

string(165) "Hello, I am John, I'm 25, I like fast cars and boats. I work as a blogger and I'm way to be continued ... <span class="highlight">author</span>"

次に、複数の<span>タグを使用した別のテスト:

これは出力します

$bio = 'Hello, what about a <span class="highlight">span tag</span> before the limit? Or what if I have many <span class="highlight">span tags</span> <span class="highlight">after</span> <span class="highlight">the</span> limit?';
$bio = limit_text( $bio,85);
var_dump( htmlentities( $bio));

string(308) "Hello, what about a <span class="highlight">span tag</span> before the limit? Or what to be continued ... <span class="highlight">span tags</span>, <span class="highlight">after</span>, <span class="highlight">the</span>" 

他にもテスト ケースがある場合、または上記の機能に変更がある場合は、お知らせください。修正できます。

于 2012-06-28T01:29:32.657 に答える
0

あなたの要件から判断すると、これはあなたが望むことをするはずです:

function get_highlighted_string($s)
{
    return '<span class="highlight">' . htmlspecialchars($s) . '</span>';
}

function limit_text($text, $max_length, array $keywords = array(), $continued = '...')
{
    // highlights to put after the cut string
    $extra = array();

    // highlight keywords
    if ($keywords) {
        $re = '~\b(' . join('|', array_map('preg_quote', $keywords, array('~'))) . ')\b~i';
        // get all matches and capture their positions as well
        if (preg_match_all($re, $text, $matches, PREG_OFFSET_CAPTURE)) {
            // we reverse the matches by position to make replacement easier
            foreach (array_reverse($matches[1]) as $match) {
                // $match[0] = match
                // $match[1] = start position
                $match_len = strlen($match[0]);
                if ($match[1] + $match_len <= $max_length) {
                    // still fits in cut string
                    $match_replacement = get_highlighted_string($match[0]);
                    $text = substr_replace($text, $match_replacement, $match[1], $match_len);
                    // update max length
                    $max_length = $max_length - $match_len + strlen($match_replacement);
                } else {
                    // will not fit in the cut string, so we place it outside
                    array_unshift($extra, get_highlighted_string($match[0]));
                }
            }
        }
        // use wordwrap and strcspn to cut the string by word boundaries
        if (strlen($text) > $max_length) {
            $text = substr($text, 0, strcspn(wordwrap($text, $max_length, "\0"), "\0")) . " $continued";
        }
    }

    if ($extra) {
        // append what we couldn't fit in the cut string
        $text .= ' ' . join(', ', $extra);
    }

    return $text;
}

例:

echo limit_text("Hello, I like fast cars and boats. I work as a blogger I'm way cooler then the author of the question", 85, array('author', 'question'));

Hello, I like fast cars and boats. I work as a blogger I'm way cooler then the <span class="highlight">author</span> ... <span class="highlight">question</span>

この例では、カットオフがちょうど にあるauthorため、ハイライトが の前に来て...questionキーワードが後ろに置かれます。

もう一つの例:

echo limit_text("Hello, I am John, I'm 25, I like fast cars and boats. I work as a blogger and I'm way cooler then the author of the question", 85, array('author', 'question'));

Hello, I am John, I'm 25, I like fast cars and boats. I work as a blogger and I'm way ... <span class="highlight">author</span>, <span class="highlight">question</span>

どちらのキーワードも 85 文字のマーカーを超えているため、後ろにカンマ区切りで追加されます。

これがうまくいくかどうか教えてください:)

于 2012-06-28T06:11:31.967 に答える