$t = 'Проблема в следующем:
Есть слова (поисковый запрос), есть текст содержащий эти слова.
По какому принципу (алгоритму) выбрать цитаты из текста, чтобы они максимально точно соответствовали запросу?
Например:
1 слово: просто выбираем любой фрагмент, в котором присутствует это слово,
2 слова: выбираем фрагмент, где эти слова наиболее близко друг к другу расположены (или если они далеко друг от друга – 2 фрагмента, каждый из которых содержит одно из слов);
а как быть с тремя и более словами? тест фрагмент слово тест
Буду рад любой помощи (идее, алгоритму, готовому решению). ';
$q = 'слов фрагмент';
preg_match_all('~\S+~',$q,$m);
$words = $m[0];
// тут по сути надо извлекать корень из всех слов, сам сделаешь через стеммер Портера который есть на dklab.ru
$expr = '';
for ($i = 0, $s = sizeof($words); $i < $s; ++$i)
{
$expr .= preg_quote($words[$i],'~').($i+1 < $s?'|':'');
}
//setlocale(LC_ALL,'ru_RU.UTF-8');
preg_match_all('~(?:\W.{0,50}?\W)?\w*(?:\s*(?:'.$expr.')\s*)+\w*(?:\W.{0,50}?\W)?~',$t,$m);
$fragments = array();
for ($i = 0, $s = sizeof($m[0]); $i < $s; ++$i)
{
$f = preg_replace('~^[\,\.\!\(\);\s]+|[\,\.\!\(\);\s]+$~','',$m[0][$i]);
$fragments[] = $f;
}
// далее если надо поискать где ближе всего
$min_l = $max_c = $min_id =-1;
for ($i = 0, $s = sizeof($fragments); $i < $s; ++$i)
{
preg_match_all('~'.$expr.'~',$fragments[$i],$m);
for ($j = 0, $g = sizeof($m[0]); $j < $g; ++$j) {$m[0][$j] = strtolower($m[0][$j]);}
$n = sizeof(array_unique($m[0]));
if ($n <= $max_c) {continue;}
if (!preg_match('~(?:'.$expr.').*(?:'.$expr.')~',$fragments[$i],$h))
{
if ($min_id == -1) {$min_id = $i; $min_c = $n;}
continue;
}
$w = $h[0];
$v = strlen(preg_replace('~'.$expr.'~','',$w));
if ($v >= $min_l and $min_l != -1) {continue;}
$min_id = $i;
$min_c = $n;
$min_l = $v;
}
var_dump($fragments[$min_id],$fragments);
/*
string(24) "тест фрагмент слово тест"
array(12) {
[0]=>
string(24) "в следующем:
Есть слова"
[1]=>
string(40) "запрос), есть текст содержащий эти слова"
[2]=>
string(19) "Например:
1 слово:"
[3]=>
string(23) "выбираем любой фрагмент"
[4]=>
string(30) "котором присутствует это слово"
[5]=>
string(8) "2 слова:"
[6]=>
string(17) "выбираем фрагмент"
[7]=>
string(18) "эти слова наиболее"
[8]=>
string(60) "расположены (или если они далеко друг от друга – 2 фрагмента"
[9]=>
string(32) "из которых содержит одно из слов"
[10]=>
string(35) "а как быть с тремя и более словами?"
[11]=>
string(24) "тест фрагмент слово тест"
}
*/