Страницы

Поиск по вопросам

среда, 27 ноября 2019 г.

Найти в тексте слова, которые есть в базе данных

#php #mysql


Здравствуйте. В базе данных есть таблица slovo, ее структура: 

id - auto_increment 
name - само слово( уникальный )


Есть переменная: $text, которая содержит в себе некий текст.

В таблице slovo есть запись: id = 1, name = Яблоко , id = 2, name = дерево

$text = "В корзине лежит яблоко. В поле стоит дерево.";


Вопрос: каким образом определить, есть ли в переменной слова, которые находятся в
таблице slovo, и если есть, то эти слова выделить в слово
, где id_slovo - значение id для этого слова из базы.

P.S. Учитывая то, что может быть и словосочетания. 

Буду очень благодарен за любую полезную информацию.
    


Ответы

Ответ 1



//Сначала нужно найти все слова, бьем фразу в массив по пробелам $words = explode(' ', $text); //Затем проверяем каждое слово: foreach($words as $word) { $word = trim($word); //убираем пробелы //Проверяем в базе, любимым адаптером выполняя запрос //Само собой никто не мешает заменить ILIKE на LIKE или = $wordId = $msSql->fetchOne("SELECT id FROM slove WHERE name ILIKE '{$word}'"); //Если в базе такое слово есть, то заменяем его в тексте на нужный span if (!empty($wordId)) { $text = str_replace($word, "$word", $text); } }

Ответ 2



$text = "В корзине лежит яблоко. В поле стоит дерево."; // все слова из таблицы, присутствующие в тексте получаем одним запросом $result = mysql_query("SELECT id, name FROM slovo WHERE INSTR('" . mysql_escape_string($text) . "', name)"); // проходим по всем словам и делаем замену while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) { $text = str_ireplace($row['name'], '' . $row['name'] . '', $text); }

Ответ 3



PHP MySQL PDO Думаю что такое вот решение подойдет class ConnectPDO { private $connect = array( 'login' => 'DB_USER', 'password' => 'DB_PASS', 'db' => 'slovo_db' ); private $dbc; public function __construct() { $db_name=$this->connect['db']; $this->dbc = new PDO("mysql:host=localhost;dbname=$db_name;charset=utf8", $this->connect['login'], $this->connect['password']); } } $connection=new ConnectPDO(); $sth = $connection->dbc->prepare("SELECT * FROM `slovo` WHERE `name` LIKE %:name% "); $data = array(); $text = "asd sad asd as dasd asd asdasdas das das das"; //explode делает массив из фразы с которым далее очень просто работать $text_aray = explode(" ", $text); foreach ($text_aray as $each) { $sth->execute(array('name'=>$each)); $result = $sth->fetchAll(); $data[] = $result; } // отобразить все слова из базы foreach ($data as $data_block){ foreach ($data_block as $each_row){ echo ''.$each_row['name'].'
'; } } параметры, которые нужно заменить на на свои: DB_USER юзер mysql DB_PASS пароль mysql slovo_db база mysql

Ответ 4



$text = "В корзине лежит яблоко. В поле стоит дерево."; //заменяем несколько пустых символов на один (чтобы избежать ситуации, когда из-за нескольких пробелов сочетания не будут найдены) $text = preg_replace('/\s{2,}/', ' ', $text); //подключаемся к базе данных (на примере MYSQL, подправите под свою базу) и выбираем // все слова из таблицы, присутствующие в тексте получаем одним запросом, сортируем по уменьшению длины слов (фраз). // Это нужно, чтобы исключить вариант когда при наличии 2-х слов/фраз "яблоко", "лежит яблоко" после замены первого, // второе не получится уже заменить, так как между ними уже будет span try{ $link = new PDO( 'mysql:host=your-hostname;dbname=your-db;charset=utf8mb4', 'your-username', 'your-password', array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_PERSISTENT => false ) ); $handle = $link->prepare('SELECT id, name FROM slovo WHERE INSTR(?, name) ORDER BY CHAR_LENGTH(name) DESC'); $handle->bindValue(1, $text, PDO::PARAM_STR); $handle->execute(); $result = $handle->fetchAll(PDO::FETCH_OBJ); // проходим по всем словам и делаем замену foreach($result as $row){ //экранируем служебные символы " . \ + * ? [ ^ ] $ ( ) { } = ! < > | : - " $word = preg_quote($row->name); //используем регулярное выражение чтобы: //1) после замены регистр слов не был изменён //2) были заменены полностью слова а не только вхождения, например при слове "дерево", слово "деревообработка" останутся не тронутыми $text = preg_replace('/(^|\W)(' . $word . ')($|\W)/iu', '\\1\\2\\3', $text); } } catch(PDOException $ex){ print($ex->getMessage()); } если вы хотите использовать морфологию (например библиотеку phpMorphy), то я бы рекомендовал: 1) если количество записей в таблице slovo не большое, делать полную выборку $handle = $link->prepare('SELECT id, name FROM slovo ORDER BY CHAR_LENGTH(name) DESC'); $handle->execute(); 2) если количество записей в таблице slovo большое, то для уменьшения времени замены добавить в таблицу slovo столбик, в который помещать корень слова (можно автоматически через библиотеку) и по нему делать фильтрацию INSTR(?, new_column). 3) После при переборе слов перед $word = preg_quote($row->name); сделать загрузку всех вариантов слова, а после сделать preg_replace для каждого варианта. Решение не оформлялось в виде класса, так как, насколько я понимаю, это будет частью вашей задачи. здесь сосредоточено только на основных моментах.

Ответ 5



example 1, "name"=>"яблоко"); echo 'before:'.$text."\n\t"; f_process_text($text, $replacement_arr); echo 'after:'.$text."\n"; function f_process_text(&$text, $replacement_arr){ #set morphological phrases for $replacement_arr["name"]; $phrases = f_get_phrases($replacement_arr["name"]); list($patterns, $replacements) = f_get_prepared_fo_replacement_arrs($phrases, $replacement_arr["id"]); $text = preg_replace( $patterns, $replacements, $text); } #return array function f_get_phrases($words){ $result = array(); $result[] = $words; #to add phrases it is recomended to use [phpMorphy](http://phpmorphy.sourceforge.net/) return $result; } function f_get_prepared_fo_replacement_arrs($phrases, $id){ $patterns = array(); $replacements = array(); foreach($phrases as $phrase){ $patterns[] = '/'.$phrase.'/'; $replacements[] = ''.$phrase.''; } return array($patterns, $replacements); } ?>

Ответ 6



Вот такой касс у меня вышел: text = $text; } if (!empty($phrases)) { $this->phrases = $phrases; } } /** * Получить текст с заменами * @return string */ public function getReplacedText() { if (empty($this->patterns) || empty($this->replacements)) { list($this->patterns, $this->replacements) = $this->getPatterns(); } return preg_replace( $this->patterns, $this->replacements, $this->text); } /** * Формируем массивы для поиска и замены * @return array */ protected function getPatterns() { $patterns = []; $replacements = []; foreach ($this->phrases as $phrase) { $name = preg_quote($phrase['name']); $patterns[] = '/('.$name.')/iu'; $replacements[] = '$1'; } return [$patterns, $replacements]; } /** * @return string */ public function getText() { return $this->text; } /** * @param string $text * @return PhrasesReplacement */ public function setText(string $text) { $this->text = $text; return $this; } /** * @return array */ public function getPhrases() { return $this->phrases; } /** * @param array $phrases * @return PhrasesReplacement */ public function setPhrases(array $phrases) { $this->patterns = []; $this->replacements = []; $this->phrases = $phrases; return $this; } } Работать с ним так: $text = "В корзине лежит яблоко. В поле стоит дерево."; $phrases = [ ['id' => 1, 'name' => 'корзине лежит'], ['id' => 2, 'name' => 'дерево'], ]; $replacer = new PhrasesReplacement($text,$phrases); echo $replacer->getReplacedText() . "\n"; $text2 = "В корзине ЛеЖаТ Яблоки. В поле стоит дерево."; echo $replacer->setText($text2)->getReplacedText() . "\n"; $phrases = [ ['id' => 1, 'name' => 'лежат яблоки'] ]; echo $replacer->setPhrases($phrases)->getReplacedText() . "\n"; Ну и соответственно из базы удобнее всего будет получать значения так: $dsn = 'mysql:dbname=dbname;host=127.0.0.1;port=3306'; $user = 'root'; $pass = 'root'; $pdo = new PDO($dsn, $user, $pass); $sql = 'SELECT `id`, `name` FROM `slovo`;'; $stmt = $pdo->prepare($sql); $stmt->setFetchMode(PDO::FETCH_ASSOC); $stmt->execute(); $phrases = $stmt->fetchAll();

Ответ 7



Один вариант: $dsn = 'mysql:host=localhost;dbname=...'; $user = '...'; $password = '...'; $text = "В корзине лежит яблоко. В поле стоит дерево."; // исходная строка $max_count_of_replace = count(explode(' ', $text)); // максимальное кол-во замен в исходной строке $opt = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]; try { $pdo = new PDO($dsn, $user, $password, $opt); } catch (PDOException $e) { die('Ошибка: ' . $e->getMessage()); } $sql = 'SELECT `id`, `name` FROM `slovo` WHERE INSTR(:text, `name`)'; $stmt = $pdo->prepare($sql); $stmt->bindValue(':text', $text, PDO::PARAM_STR); $stmt->execute(); // заменяем слова из таблицы, присутствующие в $text $count_of_replace = 0; foreach ($stmt as $row) { $text = str_ireplace($row['name'], "{$row['name']}", $text, $count); $count_of_replace += $count; if ($count_of_replace > $max_count_of_replace) { break; } } echo $text; // результат Идея состоит в использовании MySQL-функции: INSTR() + добавлено ограничение на максимальное кол-во замен. Второй вариант: Не используем INSTR(), например, если хочется независимости от СУБД. PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]; try { $pdo = new PDO($dsn, $user, $password, $opt); } catch (PDOException $e) { die('Ошибка: ' . $e->getMessage()); } $sql = 'SELECT `id`, `name` FROM `slovo`;'; $stmt = $pdo->prepare($sql); $stmt->execute(); $count_of_replace = 0; foreach ($stmt as $row) { $text = str_ireplace($row['name'], "{$row['name']}", $text, $count); $count_of_replace += $count; if ($count_of_replace > $max_count_of_replace) { break; } } echo $text; // результат

Комментариев нет:

Отправить комментарий