2012-03-21 6 views
1

У меня есть интересная проблема, когда я выделяю текст из массива ключевых слов, используя PHP str_ireplace().Выделение текста с 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 никогда не получит утра ATCH потому eggs уже заменены в тексте как:

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

Там также могут быть случаи, когда имеет место частичное дублирование таких как:

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

Что такое умный способ решения такого рода вопроса ?

+0

не забудьте посмотреть 'зеленые яйца', иначе у вас есть,' зеленые зеленые яйца' –

ответ

1

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

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

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

+0

Спасибо animuson! Я подумал об этом, но что, если у нас есть «зеленые яйца» и «яйца»? Я также хотел бы позаботиться о случаях частичного перекрытия. –

1

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

$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. 
+0

Поблагодарите ioums, но мне действительно нужно сохранить каждую часть перекрытия, потому что это должно быть специально отмечено в тексте. –

Смежные вопросы