Выделение текста с помощью str_ireplace () - PullRequest
1 голос
/ 21 марта 2012

У меня есть интересная проблема, когда я выделяю текст из массива ключевых слов, используя PHP str_ireplace().

Допустим, это мой массив ключевых слов или фраз, которые я хочу выделить из образца текста:

$keywords = array('eggs', 'green eggs');

А это мой пример текста:

$text = 'Green eggs and ham.';

Вот как я выделяю текст:

$counter = 0;
foreach ($keywords as $keyword) {
    $text = str_ireplace($keyword, '<span class="highlight_'.($counter%5).'">'.$keyword.'</span>', $text);
    $counter++;
}

Проблема в том, что green eggs никогда не получит совпадения, потому что eggs уже заменено в тексте следующим образом:

Green <span class="highlight_0">eggs</span> and ham.

В некоторых случаях возможны частичные совпадения, такие как:

$keywords = array('green eggs', 'eggs and'); 

Что такое умный способ решения этой проблемы?

Ответы [ 2 ]

1 голос
/ 21 марта 2012

Возможно, это не самое красивое решение, но вы можете отследить места, где встречаются ваши ключевые слова, а затем найти, где они перекрываются, и отрегулировать, где вы хотите включить теги span *.

$keywords = array('eggs', 'n eggs a', 'eggs and','green eg');
$text = 'Green eggs and ham.';
$counter = 0;
$idx_array = array();
$idx_array_last = array();
foreach ($keywords as $keyword) {
    $idx_array_first[$counter] = stripos($text, $keyword);
    $idx_array_last[$counter] = $idx_array_first[$counter] + strlen($keyword);
    $counter++;
}
//combine the overlapping indices
for ($i=0; $i<$counter; $i++) {
    for ($j=$counter-1; $j>=$i+1; $j--) {
        if (($idx_array_first[$i] <= $idx_array_first[$j] && $idx_array_first[$j] <= $idx_array_last[$i]) 
                || ($idx_array_last[$i] >= $idx_array_last[$j] && $idx_array_first[$i] <= $idx_array_last[$j])
                || ($idx_array_first[$j] <= $idx_array_first[$i] && $idx_array_last[$i] <= $idx_array_last[$j])) {
            $idx_array_first[$i] = min($idx_array_first[$i],$idx_array_first[$j]);
            $idx_array_last[$i] = max($idx_array_last[$i],$idx_array_last[$j]);
            $counter--;
            unset($idx_array_first[$j],$idx_array_last[$j]);
        }
    }
}
array_multisort($idx_array_first,$idx_array_last); //sort so that span tags are inserted at last indices first

for ($i=$counter-1; $i>=0; $i--) {
    //add span tags at locations of indices
    $textnew = substr($text,0,$idx_array_first[$i]).'<span class="highlight_'.$i.'">';
    $textnew .=substr($text,$idx_array_first[$i],$idx_array_first[$i]+$idx_array_last[$i]);
    $textnew .='</span>'.substr($text,$idx_array_last[$i]);
    $text = $textnew;
}

Выход

<span class="highlight_0">Green eggs and</span> ham.
1 голос
/ 21 марта 2012

В обратном порядке:

$keywords = array('green eggs', 'eggs');

Самый простой способ - сначала создать самые длинные строки, а затем перейти к более короткимПросто убедитесь, что вы не дублируете одну и ту же строку (если это имеет значение).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...