Суть проста-- найти кол-во вхождений 2 любых слов идущих друг за другом применительно к тексту. PHP: <? ini_set('display_errors',1); error_reporting(E_ALL); $new='hello my friend, hello my friend,hello,goodbuy my friend,hello my friend,goodbuy my friend,goodbuy, hello my friend,'; $new=preg_replace('/[-,.\;:\'\"\d)(!\s]+/'," ",$new); $new=preg_replace('/[\s]+/'," ",$new); echo $new.'<br>'; preg_match_all('/\b.+?\b\s\b.+?\b/si',$new,$match); $new=array_count_values($match[0]); arsort($new); foreach($new as $key=>$value) { if($value>1 and strlen($key)>1) { echo $key. '---'.$value.'<br>'; } } echo '<pre>'; print_r($new); echo '<pre>'; ?> Итак имеем повторов my friend --только 4 раза вместо 6. Как воплотить задачу в жизнь..??? надо задавать какое-то новое смещение в регулярке по циклу?? Вообще что можно сделать..?? как правильно прочитать текст и понять что там больше my friend и так же понимать что там много "hello my" и есть "goodbuy my" Буду рад любой помощи. Apple ты ведь наверно точно знаешь как решаются подобные задачи ?
Да сколько ж можно повторять-то одно и то же, неужели у самих головы на плечах нет: если нет логической последовательности группировки, то задача не имеет решений. Один из вариантов - тупой перебор последовательностей с указанным смещением от начала строки, т.е количество переборов будет равно количеству слов в одной группе для первого прохода. Для того, чтобы у задачи появились рациональные решения, то для начала нужно саму задачу свести к системе, а не искать решения.
Да возможно ты прав... раньше пользовался вот этой штукой для больших текстов http://www.seotxt.com/service/optimizer/ и только сейчас ввел свой простой текст и понял, что она фигово ищет фразы. Думаю смещение от начала строки на одно или два слова все равно даст мало нужных результатов. Хотя что-то явно совпадет. и этим можно тоже пользоваться. тут нужен алгоритм перескакивания через разное кол-во слов с случайной возможностью попадания в нужную фразу.
PHP: <?php function count_phrase($string, $step = 2) { if ($step <= 0) { die("Step must be greater than 0!"); } global $result; if (preg_match('/\w+/s', $string) == 0) { return $result; } preg_match('/(\W*\w+\W*){'.$step.'}/s', $string, $matches); $matches[0] = trim($matches[0]); if (!isset($result[$matches[0]])) { $result[$matches[0]] = substr_count($string, $matches[0]); } $string = trim(preg_replace('/^\w+[[:punct:]]*/s', "", $string, 1)); count_phrase($string, $step); } $result = array(); $string = "hello my friend, hello my friend,hello,goodbuy my friend,hello my friend,goodbuy my friend,goodbuy, hello my friend,"; echo $string."<br />"; count_phrase($string, 2); print_r($result); ?> Что делать со знаками пунктуации, решите сами.
Dima4321 PHP: <?php header("Content-type:text/plain"); $new = 'hello my friend, hello my friend,hello,goodbuy my friend,hello my friend,goodbuy my friend,goodbuy, hello my friend,'; $words = array('hello','my'); $new = explode(' ',str_replace(',',' ',$new)); //лучше бы все лишние знаки убрать $new = array_intersect($new,$words); print_r($new); ?> дальше догадаешься что делать? для подбора фраз из текста есть алгоритм цепей маркова
Padaboo Спасибо... боюсь показаться валенком , но ты точно понял пою задачу ?? массив $words с кол-ом вхождений например больше 2 одинаковых слов я получу с помощью регулярки 1) \b.+?\b 2) и функции $new=array_count_values($match[0]); 3) выеду массивом где кол-о одинкаовых слов будет больше двух foreach($new as $key=>$value) { if($value>2 and strlen($key)>2) { echo $key. '---'.$value.'<br>'; } } Дальше по твоей логике я буду сравнивать слова со словами в массивах...а смысл ??? Мне нужны четкие фразы !!! Кол-во вхождений одинаковых слов я и так узнал с помощью пункта 1 и 2. Мне нужно кол-во вхождений фраз. Фраз текст которых я изначально не знаю. Я валенок ??? только честно ??))
Dima4321 хз, из моего массива если лишний my исключить получится количество (5) идущих друг за другом фраз hello * my hello my hello my hello,goodbuy my hello my hello my
Хотя появилась идея, что можно одинаковые слова пустить снова в текст и помещать в массив ближайшие слова включительно с этим словом. т.е. нашли что существуют одинаковые слова с хорошей плотностью hello my friend пустили их через preg_match_all и вывели эти слова уже как фразу( т.е. слово поиска захватило ближайшее слово) : hello my friend hello Потом останется лишь выбрать массивы фраз с большим кол-ом вхождений .
Куча решений, а если посмотреть на задачу? Сделаем сферическую строку в вакууме: 1. Имеется строка, в которой n слов. 2. Строка представляет из себя набор конечный символов [a-zA-Z0-9-], всё остальное - разделители 3. Требуется найти количество одинаковых фраз, где фраза - это количество элементов типа "слово" 4. Разбиваем строку на фразы, где фраза содержит <= 2 слова. Всего у нас выйдет строк n/2 при условии, если n - четное, и (n/2 - 1) если n - нечетное. 5. Сравнение даст положительный результат только в том случае, если количество слов между конечными фразами будет равно количеству слов во фразе, т.е мир, река, мир, мир, мир, река (шаг=2): (мир-река, мир-мир, мир-река). Если в этом множестве извлечь третий элемент, то все подсчеты логически рассыпятся.
Нет, вы просто не умеет читать форум. Сообщение №4: Код (Text): Array ( [hello my] => 4 [my friend,] => 6 [friend, hello] => 1 [friend,hello,] => 1 [hello,goodbuy] => 1 [goodbuy my] => 2 [friend,hello] => 1 [friend,goodbuy] => 2 [friend,goodbuy,] => 1 [goodbuy, hello] => 1 [friend,] => 1 )
Код (Text): world, river, world, world, world, river Array ( [world, river,] => 1 [river, world,] => 1 [world, world,] => 1 [world, river] => 1 [river] => 1 ) Код (Text): world, river, world, world, river Array ( [world, river,] => 1 [river, world,] => 1 [world, world,] => 1 [world, river] => 1 [river] => 1 ) Код можно легко доработать, чтобы пропускать разделители.
А мне даже не все понятно..но здорово..как некрутил вставлял фразы в середину ..все равно ищет четко совпадения.. сам придумал или подглядел..опиши принцип ???)) Вот видишь Apple есть еще светлые головы. Главное желание !
Доработка на случай разделителей: PHP: <?php function prepare_phrase($string, $step = 2) { if ($step <= 0) { die("Step must be greater than 0!"); } $string = preg_replace('/\W+/s', " ", $string); $string = trim(preg_replace('/\s+/s', " ", $string)); return count_phrase($string, $step); } function count_phrase($string, $step) { global $result; if (preg_match_all('/\w+/s', $string, $pockets) == $step - 1) { return $result; } preg_match('/(\s?\w+\s?){'.$step.'}/s', $string, $matches); $matches[0] = trim($matches[0]); if (!isset($result[$matches[0]])) { $result[$matches[0]] = substr_count($string, $matches[0]); } $string = preg_replace('/^\w+\s?/s', "", $string); count_phrase($string, $step); } $result = array(); $str = "hello my friend, hello my friend,hello,goodbuy my friend,hello my friend,goodbuy my friend,goodbuy, hello my friend,"; //$str = "world, river, world, world, river"; //$str = "world, river, world, world, world, river"; echo $str."<br />"; prepare_phrase($str, 2); print_r($result); ?> Простая рекурсия. В функции prepare_phrase() подготавливаем строку: все разделители заменяем на одиночные пробелы.Подготовленную строку передаем в рекурсионную функцию count_phrase(). В функции при помощи регулярки находим первые два слова (фраза). Считаем количество совпадений этой фразы во всей строке. Удаляем первое слово в строке и передаем новую строку в рекурсию. Так работаем пока в строке не останется одно слово. Когда останется одно слово - останов рекурсии и возврат результирующего массива. Результирующий массив: ключи есть фразы, значения есть число совпадений. Наблюдается баг с функцией substr_count: PHP: <?php $str = "world world world"; echo substr_count($str, "world world").; ?> Результат 1, а должно быть 2.
Мое решение свелось к этому: PHP: preg_match_all('/\b.+?\b/si',$new,$match); $n=array_count_values($match[0]); arsort($n); foreach($n as $key=>$value) { if($value>7 and strlen($key)>=4) { preg_match_all("/$key\s\b.+?\b/si",$new,$match); foreach($match[0] as $value) { echo $value; echo '<br>'; } } } так же замечу , что код работает не сликом корректно на больших текстах и почему-то упускает несколько слов. и кстати вот такой кусок почему-то не работает вовсе PHP: foreach($n as $key=>$value) { if($value>7 and strlen($key)>=4) { preg_match_all("/\b.+?\b\s$key/si",$new,$m); foreach($m[0] as $value) { echo $value; echo '<br>'; } } } захватывает весь текст
И вот еще: http://www.seotxt.com/service/optimizer/ Эта штука все таки работает корректно !! Интересно у нее такой же код как и уJampire )) ??
Вот упрощенный мой код. Вроде работает как надо. Попробуйте сделать тест из простой строки. Мне даже не верится что я сделал что-то похожее на анализатор..)) Не усну. первый массив вхождение двух слов второй массив вхождение одного слова. PHP: <? ini_set('display_errors',1); error_reporting(E_ALL); $new='derevo staroe derevo hello my hello my hello my fedor misha hello my hello dima hello my staroe derevo hello dima hello dima staroe derevo '; echo $new.'<br>'; preg_match_all('/\b.+?\b/si',$new,$match); $n=array_count_values($match[0]); arsort($n); $r=""; foreach($n as $key=>$value) { if($value>=3 and strlen($key)>1) { preg_match_all("/$key\s\b.+?\b/si",$new,$match); foreach($match[0] as $value) { $r .=$value.'<br>'; } } } $rr=preg_split('/<br>/',$r); $v=array_count_values($rr); arsort($v); echo '<pre>'; print_r($v); echo '</pre>'; echo '<pre>'; print_r($n); echo '<pre>'; ?>
Когда-то давно я решал такую задачу, когда хотел найти в своей статье часто повторяющиеся выражения. Для этого использовал регулярные выражения. Проблема в том, что это выражение ищет повторы слов и фраз из любого количества слов. Но думаю под свои нужды переделаете. PHP: <?php $text = 'derevo staroe derevo hello my hello my hello my fedor misha hello my hello dima hello my staroe derevo hello dima hello dima staroe derevo'; preg_match_all('/(?=(\b\w+(?:\s+\w+)*\b).*?\1)/', $text, $k); $words = array_unique($k[1]); $res = array(); foreach($words as $v) $res[$v] = substr_count($text, $v); arsort($res); print_r($res);