Вернуться   ИнформКлуб - то, что надо! > Научись и научи! > Web программирование > PHP


Comment
 
Tutorial Tools Опции просмотра
Рекомендуемые Учебники
Пишем синонимайзер на PHP

Пишем синонимайзер на PHP

Опубликовал(а) Gostemilov
01.09.2017
По умолчанию Пишем синонимайзер на PHP

Определимся с форматом словаря.

Я для себя остановился на таком,

Код:
слово => синоним | синоним | синоним | ...
слово1 => синоним | синоним
слово2 => @слово
...


так как для работы с ним уже был написан код для другого проекта.

@собачка указывает что синоним является алиасом для другого синонима.


Поиски в сети не предоставили мне удобоваримых форматов словарей, поэтому пришлось писать конвертор найденного в наш формат.

Сниппет словаря, который нужено сконвертить в наш формат

Код:
белок# || вытаращить арабские белки
Белый#, белоснежный, светлый, седой. Белее снега. См. чистый || профессор белой и черной магии, сделать белее снега, сказка о белом бычке, сказка про белого бычка
бельмес# || ни бельмеса, ни бельмеса не смыслить
бельмо# || вылупить бельма, выпучить бельма, выпялить бельма, вытаращить бельма, налить бельма
беляк (-чка)# [опрятный человек, щеголек (Даль, белый)] см. франт
бенефис# || устроить бенефис
Бередить#, вередить, растравлять, растрагивать, задевать. Ср. <Возбуждать>.
Бережливость#, бережь, домовитость, расчетливость, экономия. "Бережь лучше прибытка" (посл.).
Бережливый#, бережный, домовитый, расчетливый, экономный, хозяйственный, умеренный. Жить с расчетом (бережливо). Ср. <Скупой>. Прот. <Расточительный>. См. скупой
бережь# [береженье и бережливость; охрана, сохранение; осторожность (Даль)] см. бережливость, заботливость
Строчим код конвертора

Файл dicconv.php - Конвертор словаря

<?php
setlocale (LC_ALL, 'ru_RU.CP-1251');
#исходный словарь
$buffer = file_get_contents("original.txt");
#step1
$buffer = preg_replace("/\[.*\] см\./mU", "", $buffer);
$buffer = preg_replace("/\(.*\)/U", "", $buffer);
$buffer = preg_replace("/\<.*\>/U", "", $buffer);
$buffer = preg_replace("/^(.*)\..*$/mU", "$1", $buffer);
$buffer = str_replace('||', '', $buffer);
$buffer = str_replace(array('#,', '# ,'), '#', $buffer);
$buffer = str_replace('#', ' =>', $buffer);
$buffer = str_replace(',', ' |', $buffer);
$buffer = strtolower($buffer);

$abuffer = explode("\n", $buffer);
$kbuffer = array();

foreach ($abuffer as $v) {
$_v = explode('=>', $v);
$_k = trim($_v[0]);
$_ak = explode('|', $_k);
$_k = preg_replace("#^([\w[:space:]]+).*$#", "$1", $_k);

$_v = trim($_v[1]);
if (!empty($_k) && !empty($_v)) {
$kbuffer[$_k] = $_v;

if (count($_ak) > 1) {
array_shift($_ak);
foreach ($_ak as $_akv) { if (($__akv = trim($_akv)) && !empty($__akv)) $kbuffer[$__akv] = "@{$_k}"; }
}

}
}

uksort($kbuffer, "kcmp");
#implode to text
$buffer = '';
unset($abuffer);

foreach ($kbuffer as $k => $v) {
$buffer .= sprintf("%s => %s\n", $k, $v);
}

$buffer = preg_replace("#[\040]{2,}#", ' ', $buffer);

#done - кладем словарь в файл dic.txt
file_put_contents('dic.txt', $buffer);

/// callback
function kcmp($a, $b) { return strlen($a) > strlen($b); }


Имеем - словарь original.txt. Запускаем скрипт php ./dicconvert.php, на выходе получаем файл dic.txt,
ключи (синонимы) упорядочены по длине фразы - так чтобы короткие слова заменялись сразу, длинные - в конце.

Код:
белок => вытаращить арабские белки
волос => шерсть | щетина | пух | пушок | ворса; вихор | грива | хохол | челка | чуб | шевелюра | коса | борода | усы | бакенбарды | бакены | баки | висок | кудер | косма | прядь
антик => редкость | чудак
впрок => заготовлять впрок | не впрок
багаж => вещи | кладь | поклажа | клажа | ноша | груз | фрахт
вкось => и вкривь | и вкось
беляк => франт
...


Этот файл съест в последствии наш обработчик словаря.

Класс synonimizer.class.php - Парсер словаря

Собственно библиотека для работы со словарем.

Класс может использоваться автономно, пример:

$syn = new synonimizer();
$result_text = $syn->syn("любой текст");



В конструкторе читаем файл dic.txt и разбирает его в миссив внутреннего фомата.
Для наблюдения за процессом предусмотрена константа DEBUG, установка которой выдаст при работе
в консоль отладочную информацию о выполненых заменах.

<?php

class synonimizer {

const DEBUG = 0;

const ROW_DELIM = '=>';
const VALUE_DELIM = '|';

private $_dic_file = 'dic.txt';

/**
* @private array 'syn' = array(value, value, value)
*/
private $parsed = array();


function __construct() {

$_parsed = file(dirname(__FILE__) . '/' . $this->_dic_file);

foreach ($_parsed as $k => $v) {
$v = trim($v);
if (empty($v) || 0 === strpos($v, '#')) {
; // nop
}
else {
$v = explode(self::ROW_DELIM, $v);
$_key = trim($v[0]);
$_data = array();
if (strpos($v[1], self::VALUE_DELIM) !== false) {
$data = explode(self::VALUE_DELIM, $v[1]);
foreach ($data as $dk => $dv) {
$_data[$dk] = trim($dv);
}
}
else {
$_data = array(trim($v[1]));
if (strpos($_data[0], '@') === 0) {
// this is alias
$_data = $this->parsed[substr($_data[0], 1)];
}
}

// save
$this->parsed[$_key] = $_data;
}
}
}

/**
* Callback
*/
static $_c_matches = false;
static function syn_callback($matches) {
$out = $matches[2];
if (self::DEBUG) echo " -- " . $out . "\n";
if (!empty(self::$_c_matches)) {
$i = count(self::$_c_matches) - 1;
$i = ($i > 0) ? mt_rand(0, $i) : 0;
$out = self::$_c_matches[$i];
}
if (self::DEBUG) echo " ++ " . $out . "\n\n";
return $matches[1] . $out . $matches[3];
}

private static $index = 0;

public function syn($text) {

$text = ' ' . str_replace(array('\r\n', '\n'), "\r\n", $text) . ' ';
self::$index++;
echo ">>> " . self::$index . "\n";

if (self::DEBUG) {
echo str_repeat("-", 80) . "\n" . wordwrap($text, 80) . "\n" . str_repeat("-", 80) . "\n\n";
}

foreach ($this->parsed as $key => $matches) {
self::$_c_matches = &$matches;
$text = preg_replace_callback(
'#([^\w\d\-])(' . preg_quote($key) . ')([^\w\d\-])#i'// ([^\w\d\-]) //([\s\.\,])
, 'synonimizer::syn_callback'
, $text
);

}

$text = str_replace("\r\n", '\r\n', substr($text, 1, -1));
if (self::DEBUG) echo "--> " . wordwrap($text, 80) . " \n\n";
return $text;
}
}



Предполагается, что у нас имеется достаточно большой дамп таблицы в файле source.1251.sql.
В нем нам нужно отсинонимизировать поля title, text, description.

UPDATE `texts` SET `id` = 1,`title` = 'Под Тверью открылся рок-фестиваль "Эммаус-2006"',
`description` = 'За два дня здесь ожидается \nвыступление более 20 начинающих групп. Как говорят зрители \nфестиваля: "В его афише хорошие музыканты, это привлекает, как \nи само место проведения, все здорово!".'
WHERE `ss_news_export_news`.`id` = 1;

UPDATE `texts` SET `id` = 2,`title` = 'Samsung представил новый игровой телефон',
`description` = 'Компания Samsung Electronics представила новый игровой сотовый телефон. Мобильник SCH-B450 будет отличаться стильным дизайном и широким набором мультимедийных функций. Видеоадаптер мобильника позволит запускать на SCH-B450 игры с трехмерной графикой, а сп',`category_id` = 2,
WHERE `ss_news_export_news`.`id` = 2;


...


Файл synmake.php - Синонимайзер

На входе - дамп, на выходе - файл result.sql.
Разницу между файлами можно оценить diffом или под виндой например с помощью winmerge.

<?php
$source = "source.1251.sql";
require "synonimizer.class.php";
ob_implicit_flush(true);

$syn = new synonimizer();
$buffer = file_get_contents($source);

echo "working...\n";

function kupper($matches) {
return '. ' . ucfirst($matches[1]);
}

// функция обратного вызова
function kreplace($matches)
{
GLOBAL $syn;
$text = $syn->syn($matches[2]);
$text = preg_replace_callback('#\. ([а-я]+)#', "kupper", $text);
$text = ucfirst($text);
$text = $matches[1] . $text . $matches[3];
return $text;
}

$buffer = preg_replace_callback(
'#(`(?:title|text|description)` = \')(.*)(\')#U',
"kreplace",
$buffer);


file_put_contents('result.sql', $buffer);



Синонимайзер дополнительно сделает прописными все буквы слов, идущих после точки или стоящих в начале предложения.

Стартовый файл start.bat Для windows, юниксойды добавляют в начало #!/usr/local/bin/php и запускают

Код:
@echo off chcp 1251
php synmake.php

Запускаем, получаем результаты.

Информация
Источник
skillz.ru/dev/php/ar...

Tutorial Tools

Comment

Tutorial Tools
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Текущее время: 16:15. Часовой пояс GMT.


Почитать

Анекдоты
Афоризмы
Поговорки
Пословицы
Форум
Цитатник

Посмотреть

Галерея PNG клипарта
Галерея бесшовных фонов

Скачать

Файловый архив
Скрипты
Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2018, vBulletin Solutions, Inc. Перевод: zCarot