$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<span id="word-' . $row->id . '">\\2</span>\\3', $text); } } catch(PDOException $ex){ print($ex->getMessage()); }
if you want to use morphology (for example, the phpMorphy library), then I would recommend:
1) if the number of records in the slovo table is not large, do a full selection
$ handle = $ link-> prepare ('SELECT id, name FROM slovo ORDER BY CHAR_LENGTH (name) DESC'); $ handle-> execute ();
2) if the number of records in the slovo table is large, then to reduce the replacement time, add a column in the slovo table into which to put the word root (can be automatically through the library) and filter INSTR (?, New_column) by it.
3) After when sorting words before
$word = preg_quote($row->name);
make download all variants of the word, and after make preg_replace for each option.
The decision was not formalized as a class, since, as I understand it, this will be part of your task. here is focused only on the main points.