Страница 1 из 3

синонимайзер

Добавлено: 2008-09-24 18:50:46
Alex Keda
пишу сабж.
коду три строки, но никак не вкурю где я неправ.
итак. имеем.
достаём из БД словечки:

Код: Выделить всё

// исходные пустые массивы
$words = array();
$synonyms = array();

// строим запрос
$sql = "SELECT * FROM `news_synonyms` WHERE `active`='1'";
// делаем запрос к БД
$spisok = main_sql_query("$sql");
while($row_id = mysql_fetch_assoc($spisok)){	// перебор слов
	// загоняем слово
	array_push($words, " " . $row_id['source_word'] . " ");
	// заоняем синоним
	array_push($synonyms,  " " . $row_id['destination_word'] . " ");
}	// закрытие перебора слов
собсно замена

Код: Выделить всё

					if($GLOBALS['news_synonymization'] == 1){	// надо 
						$news_text = str_replace  ($words, $synonyms, $news_text);
					}	// закрытие синонимизации
таблица

Код: Выделить всё

-- phpMyAdmin SQL Dump
-- version 2.11.9.2
-- http://www.phpmyadmin.net
--
-- Хост: localhost
-- Время создания: Сен 24 2008 г., 19:48
-- Версия сервера: 5.0.67
-- Версия PHP: 5.2.6

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

--
-- База данных: `doorways_auto`
--

-- --------------------------------------------------------

--
-- Структура таблицы `news_synonyms`
--

CREATE TABLE IF NOT EXISTS `news_synonyms` (
  `id` int(6) NOT NULL auto_increment,
  `source_word` varchar(127) NOT NULL,
  `destination_word` varchar(127) NOT NULL,
  `active` int(1) NOT NULL default '1',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `source_word` (`source_word`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 COMMENT='синонимы уникализации новостей' AUTO_INCREMENT=14 ;

--
-- Дамп данных таблицы `news_synonyms`
--

INSERT INTO `news_synonyms` (`id`, `source_word`, `destination_word`, `active`) VALUES(1, 'зарядке', 'подзарядке', 1);
INSERT INTO `news_synonyms` (`id`, `source_word`, `destination_word`, `active`) VALUES(2, 'продемонстрируют', 'покажут', 1);
INSERT INTO `news_synonyms` (`id`, `source_word`, `destination_word`, `active`) VALUES(3, 'сперва', 'вначале', 1);
INSERT INTO `news_synonyms` (`id`, `source_word`, `destination_word`, `active`) VALUES(4, 'премьера', 'презентация', 1);
INSERT INTO `news_synonyms` (`id`, `source_word`, `destination_word`, `active`) VALUES(5, 'презентация', 'премьера', 0);
INSERT INTO `news_synonyms` (`id`, `source_word`, `destination_word`, `active`) VALUES(6, 'будущего года', 'следующего года', 1);
INSERT INTO `news_synonyms` (`id`, `source_word`, `destination_word`, `active`) VALUES(7, 'тыс.', 'тысяч', 1);
INSERT INTO `news_synonyms` (`id`, `source_word`, `destination_word`, `active`) VALUES(8, 'стоимостью', 'ценой', 1);
INSERT INTO `news_synonyms` (`id`, `source_word`, `destination_word`, `active`) VALUES(9, 'исследуем', 'изучаем', 1);
INSERT INTO `news_synonyms` (`id`, `source_word`, `destination_word`, `active`) VALUES(10, 'изучаем', 'исследуем', 0);
INSERT INTO `news_synonyms` (`id`, `source_word`, `destination_word`, `active`) VALUES(11, 'конкурирует', 'соперничает', 1);
INSERT INTO `news_synonyms` (`id`, `source_word`, `destination_word`, `active`) VALUES(12, 'топлива', 'горючего', 1);
INSERT INTO `news_synonyms` (`id`, `source_word`, `destination_word`, `active`) VALUES(13, 'рулевых колёс', 'рулей', 1);
а вот теперь фокус. если активны идентификаторы 4 и 5 или 9 и 10 то слово заменяется два раза.
т.е. имеем в тексте слово премьера - на выходе получим его же =))
я так понимаю происходит следующщее

Код: Выделить всё

премьера --> презентация --> премьера
как избежать?

Re: синонимайзер

Добавлено: 2008-09-24 19:36:40
zg

Re: синонимайзер

Добавлено: 2008-09-24 20:06:24
Alex Keda
а чем мне это поможет?
у меня строки разной длинны...

Re: синонимайзер

Добавлено: 2008-09-24 20:09:11
zg
эээххх...
strtr() может вызываться с двумя аргументами. В этом случае from должен быть массивом, индексы которого трактуются как строки поиска, а соответствующие значения - как строки замены.

Re: синонимайзер

Добавлено: 2008-09-24 20:12:09
Alex Keda
пиляд =)
до второго абзаца не дочитал =)

Re: синонимайзер

Добавлено: 2008-09-24 20:13:02
zg
не знаю, может оно, а может и нет...

UPD

Код: Выделить всё

<?php
$trans = array("hello" => "hi", "hi" => "hello");
echo strtr("hi all, I said hello", $trans);
?>

hello all, I said hi
тебе вроде это и надо

Re: синонимайзер

Добавлено: 2008-09-24 20:56:51
Alex Keda
работает вроде.
тока как бы этот кусок выпрямить

Код: Выделить всё

	// делаем массив с словом и заменой
	$tmp = array(" " . $row_id['source_word'] . " " => " " . $row_id['destination_word'] . " " );
	// пихаем массив в массив
	//array_push($synonyms, $tmp);
	$synonyms = array_merge ($synonyms, $tmp);
не умею я с массивами особо...
надо построить массив каким-то макаром, а вот каким - тока так изобрёл =(

Re: синонимайзер

Добавлено: 2008-09-24 21:05:30
Alex Keda

Код: Выделить всё

	$key = " " . $row_id['source_word'] . " ";
	// пихаем в массив
	$synonyms[$key] = $open_tag . " " . $row_id['destination_word'] . " " . $close_tag;
асилил =)
всем спасибо.

Re: синонимайзер

Добавлено: 2008-09-24 21:08:43
zg

Код: Выделить всё

// Выборка слов-синонимов
$sql = 'SELECT * FROM `news_synonyms` WHERE `active`="1"';
$res = mysql_query($sql);

// Слова синонимы
$words = array();

if ( $res && mysql_affected_rows() )
{
    // Заполняем слова-синонимы
    while ( $row = mysql_fetch_assoc($res) )
        $words[' '. $row['source_word'] .' '] = ' '. $row['destination_word'] .' ';
}

// Проверяем на необходимость замены
if( isset($GLOBALS['news_synonymization']) && $GLOBALS['news_synonymization'] )
{
    // Обрабатываем слова синонимы
    $news_text = strtr($news_text, $words);
}

Re: синонимайзер

Добавлено: 2008-09-24 23:20:47
Alex Keda
на одну переменную меньше, и несколько лишних проверок больше =))
некоторые переменные всегда заданы... иначе до этого этапа даже не дойдёт =)))

Re: синонимайзер

Добавлено: 2008-09-25 5:41:21
zg
lissyara писал(а):и несколько лишних проверок больше =))
угу 8)

Re: синонимайзер

Добавлено: 2008-09-25 11:07:27
MAK
lissyara писал(а):

Код: Выделить всё

	$key = " " . $row_id['source_word'] . " ";
	// пихаем в массив
	$synonyms[$key] = $open_tag . " " . $row_id['destination_word'] . " " . $close_tag;
асилил =)
всем спасибо.
Слова со знаками препинания рядом с ними не будут меняться. Нужно строить этот массив со всеми возможными знаками...

Re: синонимайзер

Добавлено: 2008-09-25 11:13:09
MAK
Например, вот так:

Код: Выделить всё

$a = array('.',',',':',';','!','?');// ну и так далее...

while ( $row = mysql_fetch_assoc($res) )
{
    $words[' '.$row['source_word'].' '] = ' '.$row['destination_word'].' ';
    foreach($a as $b)
    {
        $words[$b.$row['source_word'].' '] = $b.$row['destination_word'].' ';
        $words[' '.$row['source_word'].$b] = ' '.$row['destination_word'].$b;
    }
}

Re: синонимайзер

Добавлено: 2008-09-25 12:36:15
zg
MAK писал(а):Нужно строить этот массив со всеми возможными знаками...
пойду чтоль за попкорном 8)
MAK писал(а):$a = array('.',',',':',';','!','?');// ну и так далее...
:no: а смысл?

Re: синонимайзер

Добавлено: 2008-09-25 15:48:29
MAK
zg писал(а):а смысл?
попкорн купил? Начинай жувать, я объясню... ))

Re: синонимайзер

Добавлено: 2008-09-25 15:51:15
zg
ага, давай, я как раз печеньки ем :smile:

Re: синонимайзер

Добавлено: 2008-09-25 15:56:31
MAK
Есть исходное предложение. "Вася хотел, чтобы у его подруги был пятый размер груди."
При прогоне вашим сктиптом, с синонимом
хотел => мечтал
груди => сисек
предложение не изменится.

Re: синонимайзер

Добавлено: 2008-09-25 16:00:21
zg
ну это я понял.... токо скрипт не наш, а Лиса

Re: синонимайзер

Добавлено: 2008-09-25 16:14:04
MAK
и еще одно но, я бы заменил вызов strtr на str_replace - так надежней

Код: Выделить всё

str_replace($news_text, array_keys($words), array_values($words));
Потому что

Код: Выделить всё

Если длины строк from и to отличаются, "лишние" символы в более длинной строке не используются.

Re: синонимайзер

Добавлено: 2008-09-25 16:21:02
zg
MAK писал(а):и еще одно но, я бы заменил вызов strtr на str_replace - так надежней
:good:

ээээхххх ну вот почему читать учат с первого класса, но никто не умеет?!!!....

Re: синонимайзер

Добавлено: 2008-09-26 9:48:01
Alex Keda
zg писал(а):
MAK писал(а):и еще одно но, я бы заменил вызов strtr на str_replace - так надежней
:good:

ээээхххх ну вот почему читать учат с первого класса, но никто не умеет?!!!....
МАК, собсно с этого всё иначалось.
первый варинт глянь и грабли с ним =)))
=====
одолжил у ADRE базу синонимов на 7000 слов.
без слёз не глянешь на результат.
людям такое показывать нельзя.
либо аккуратно делать свою базу, либо показывать тока поисковикам...
поэтому препинания мне не нужны. там и так всё плохо =)))

Re: синонимайзер

Добавлено: 2008-09-26 10:25:00
zg
lissyara писал(а):людям такое показывать нельзя.
тут либо надо на С реализовывать на соортированных массивах, либо на мусе, либо грамотно продумать структуру кэширования

Re: синонимайзер

Добавлено: 2008-09-26 11:04:55
MAK
lissyara писал(а):МАК, собсно с этого всё иначалось.
первый варинт глянь и грабли с ним =)))
Да, вообще конечно эти грабли больше походят на баг. )) Или архитектурный проёб...
Зачем в массив подсовывать такие парные данные? По-моему нужно либо одно слово менять, другое. И на разных кусках текста их менять.
Отчасти поэтому и получаются такие смешные результаты... )
lissyara писал(а):одолжил у ADRE базу синонимов на 7000 слов.
без слёз не глянешь на результат.
людям такое показывать нельзя.
либо аккуратно делать свою базу, либо показывать тока поисковикам...
поэтому препинания мне не нужны. там и так всё плохо =)))
А если попробовать вариант с процентной заменой? Это прлюс к тому, что мы парные слова выкидывам.
То-есть например к каждому синониму привязать еще некий процент(можно плавающий), ну и заменять только определенное количество слов.

Re: синонимайзер

Добавлено: 2008-09-26 11:46:13
ProFTP
я вообще не понял что надо сделать, массив неполучается отсортировать? :???:

Re: синонимайзер

Добавлено: 2008-09-26 11:47:34
zg
MAK писал(а):Да, вообще конечно эти грабли больше походят на баг. )) Или архитектурный проёб...
читать-то не?
http://ru.php.net/manual/ru/function.str-replace.php

ыыыыхх
Если и search , и replace - массивы, то str_replace() использует все значения массива search и соответствующие значения массива replace для поиска и замены в subject . Если в массиве replace меньше элементов, чем в search , в качестве строки замены для оставшихся значений будет использована пустая строка. Если search - массив, а replace - строка, то replace будет использована как строка замены для каждого элемента массива search .

Код: Выделить всё

<?php
$str = 'hi all, I say hello';

$srch = array('hello', 'hi');
$rplc = array('hi', 'hello');

echo str_replace($srch, $rplc, $str);
?>
hello all, I say hello
:crazy: