Есть слово в именительном падеже, единственном числе. Нужно перевести его в другой падеж и/или число. Для PHP.
Например:
Нашел phpMorphy. В целом работает. Но не справляется с Феодосией (считает, что это мужчина по имени Феодосий). Проект не развивается, непонятно, как обновить словари.
Что еще можно использовать для этой задачи?
Решения на php я не нашел.
Зато нашел следующие альтернативы:
В итоге я написал консольный скрипт на JS, который переводит слово в нужную форму. Скрипт вызываю из PHP через exec()
, работает долго, поэтому результаты кеширую.
Для достижения хорошего результата скрипту также приходится указывать исходную форму слова, иначе возможно, что вместо существительного "пень" будет возвращен глагол "пенить".
Вот пример работы скрипта:
$ node ./az.js красный nomn plur Олег nomn gent Феодосия nomn loct Кижи nomn loct
красные
олега
феодосии
кижах
Вот сам скрипт (извините, на JS пишу как умею):
"use strict";
var tasks = [];
// Принимаем аргументы в формате:
//
// СЛОВО ИСХОДНАЯ_ФОРМА ТРЕБУЕМАЯ_ФОРМА [ СЛОВО ИСХОДНАЯ_ФОРМА ТРЕБУЕМАЯ_ФОРМА ... ]
//
// Для каждого запрошенного слова выводит результат в виде нужной формы или пустой строки,
// если преобразовать не получилось.
// Исходная/требуемая форма задается в виде набора граммем через запятую.
// Граммемы: http://opencorpora.org/dict.php?act=gram
//
// Пример:
// node ./az.js пень NOUN,nomn datv,plur Феодосия Geox loct
//
// Переводит слово "пень", которое является существительным (NOUN) (а не глаголом "пенить")
// в именительном падеже (nomn) в дательный падеж (datv) мн. число (plur) --> "пням".
// А также переводит "Феодосия" (город Geox, а не мужское имя Феодосий) к предложному
// падежу --> "Феодосии"
//
// Выводит результат на 2 строчках:
//
// пням
// феодосии
//
// Разбираем аргументы
process.argv.forEach(function (val, index, array) {
// первые два аргумента - node и script
if (index < 2) return;
// номер блока из 3 аргументов (слово, исходная, требуемая) (zero-based)
var block = Math.floor((index + 1) / 3 - 1);
// номер аргумента в блоке (zero-based)
var arg = (index + 1) % 3;
if (typeof tasks[block] === "undefined") {
tasks[block] = { word: null, form: null, inForm: null };
}
if (arg == 0) {
// слово
tasks[block].word = val;
} else if (arg == 1) {
// исходная форма
tasks[block].inForm = val.split(",");
} else {
// требуемая форма
tasks[block].form = val.split(",");
}
});
var Az = require('az');
Az.Morph.init(function() {
// выводим результат построчно
solveTasks(tasks).every(elem => console.log(elem) || true);
function solveTasks(tasks) {
var result = [];
tasks.forEach(function (val, index, array) {
// морфологический разбор
var parses = Az.Morph(val.word, { stutter: false});
// ищем в вариантах слово в нужной форме
var word = null;
for (var i in parses) {
// console.log(parses[i].word);
// console.log(parses[i].tag);
// Если tag содержит все граммемы, которые присутствовали в inForm,
// значит это наше слово.
if (arrayContainsArray(Object.keys(parses[i].tag), val.inForm)) {
// нашли
word = parses[i];
break;
}
}
if (!word) {
// не нашли
result.push("");
// result.push(val.word);
} else {
// нашли
result.push(word.inflect(val.form).word);
}
});
return result;
}
function arrayContainsArray(bigger, smaller) {
// возвращает true, если все элементы массива smaller присутствуют в bigger
// https://stackoverflow.com/questions/15514907/determining-whether-one-array-contains-the-contents-of-another-array-in-javascri
return smaller.every(elem => bigger.indexOf(elem) > -1);
}
});
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Не могу понять, почему рандомные данные которые я генерирую в функции мне не удается загрузить в БД через INSERT INTO
Суть проблемы: имеется скрипт, который должен добавлять в filetxt информацию, а если этот файл отсутствует, то создать его
Как обратится к другому файлу в PHP, чтобы только запустить скрипт, без обратной отправки результата?