Pull to refresh

Comments 141

Не хватает определение пола ещё по имени, там точность будет меньше, но тоже полезно.
Да, это было бы полезно.
Пол лучше определять по отчеству — славянские отчества у женщин кончаются на «а», у мужчин, напротив — никогда не кончаются на «а».
Писал лет 10 назад библиотеку склонений ФИО в родительный падеж, исключение — ФИО содержащие «оглы/кызы» — собственно оглы у мужчин, кызы — у женщин, так что тоже 100% попадание в пол.

По фамилии — такое-же правило, у женщин всегда «а», кроме несклоняемых фамилий. Но тут и человек не угадает по фамилии :-)
Короче, надо сделать определение пола по всем трём параметрам. Тогда точность максимальная будет.
— А ты помнишь свое отчество?
— Только последние три буквы...
©

UPD. Еще бы не возникла эта ссылка в каментах.
В одном из моих приложений есть необходимость определять пол, причем отчества может и не быть, или фамилии, я просто взял у твиттера открытые словари имен (русских и иностранных), и гружу в хэш-лист, точность определения близка к 100%, за исключением сложных случаев, например, когда женская фамилия совпадает с мужским именем. Ну и скорость при использовании HashSet не будет уступать использованию вашей простой эвристики.
Клёво. Где можно посмотреть словари и результаты?
Не нашел где оригиналы лежат, выложил у себя:

Женские(рус)
Мужские(рус)
Женские(eng)
Мужские(eng)

Списки неполные, особенно иностранные, для этого случая завожу дополнительные словари, в которые помещаю сложные варианты.
Кстати, еще идея для имен без отчества:
1) определяем по словарю мужских/женских имен
2) если имя нет в словаре, ищем людей с такой же фамилией и определяем пол по ним
3) если найдено не меньше 3х, заносим имя в словарь

Пример:
Елена Иванова — имя «Елена» в словаре женское, значит женщина
Даздраперма Иванова — ищем выборку с фамилией «Иванова», смотрим пол большинства (например, 5 — женщин, 1 — ошибочно заведенный мужик), и решаем, что Даздраперма — женщина. Так как найдено больше 3х, то заносим «Даздраперма» в словарь женских имён.
Предлагаю более железобетонный вариант:

  def detect_gender(midname)
    tail = UnicodeUtils.downcase(midname[-4, 4])
    if (tail[-1]=='а') or (tail=='кызы')
      'female'
    else
      'male'
    end
  end

Пола 'androgynous' не бывает, и неопределённость можно списать на мужчин.
По фамилии — такое-же правило, у женщин всегда «а», кроме несклоняемых фамилий.

Иван Васильевич Бунша. Фамилия склоняется.
Я же написал — «кроме несклоняемых фамилий».
«Бунша» — несклоняемая фамилия, поэтому по одной фамилии определить нельзя никак.
Склоняемая, я же написал.

Родительный: Это шляпа Бунши (не «Это шляпа Бунша»).
Дательный: Отдай книгу Бунше (не «Отдай книгу Бунша»).
Винительный: Поступила жалоба на Буншу (не «Поступила жалоба на Бунша»).
Творительный: Забор был покрашен Буншей (не «Забор был покрашен Бунша»).
Предложный: Написали статью о Бунше (не «Написали статью о Бунша»).

Собственно, по фамилии пол определить нельзя, потому что и у мужчины фамилия может заканчиваться на «а». И именно это я и иллюстрирую.
По имени тоже можно ) Насколько помню только одно женское имя не оканчивается не на а или я.
Гадя Петрович Хренова…

UPD: Я всегда буду читать все комментарии перед тем как постить…
Я, когда такое писал, определял по отчеству. У отчеств разнообразие было меньше.
Неплохо было бы веб-сервисом сделать, например.
Веб-интерфейс по ссылке в посте имеет API. В исходниках описано, как с ним работать. Возможно, будет проще подсмотреть параметры AJAX-запросов.
UFO just landed and posted this here
UFO just landed and posted this here
Верно. Примеры: Синих, Больных.
UFO just landed and posted this here
Вообще, надо сделать дополнительный флаг: русский/иностранец.

Пушкин → Пушкиным (русский)
Раскин → Раскином (американец)
Иванов → Ивановым (русский)
Сальхов → Сальховом (швед)
Безусловно, подобные флаги имели бы ценность и здорово помогали при обработки слов. Однако я не уверен, что их должен задавать конечный пользователь.
Такова, ёлки зелёные, жизнь. И Юникод так сложен, потому что сложна наша письменность.
Может быть, для isMale и isRussian придётся делать троичную логику: true/false/unknown, с угадыванием, например, по словарю.
На мой взгляд, такие вещи лучше решать привлечением дополнительных словарей, при обнаружении слова в которых выставлять флаги. Как это сейчас делается для двойных русских фамилий.
Но и словарь, собака, не опора: что будет, если написать: Лоис Макмастер Буджолд?
А это женщина!
Подскажите, в чем проблема для словаря в данном конкретном случае? Ведь Лоис — вполне себе женское имя.
В том, что это не русское имя? В словаре все имена мира не собрать, и ошибки неизбежны.
Сейчас мне сложно вспомнить какие-то исключения, спать хочется. Всё зависит от фамилии, происхождения, словоупотребительной практики. Возможно, статья на «Грамоте» поможет пролить свет.
UFO just landed and posted this here
Уже отправил в баг-трекер, у меня тоже фамилия в творительном не так склоняется (Быхун).
Библиотека несложна, «особой рубиновой магии» там вроде бы нет, и, кажется, портация на С++ должна занять день.
Сложнее будет написать юнит-тесты.
В репозитории сейчас имеются какие-то примитивные тесты на RSpec, но я их особо не читал. Процедура автоматической оценки по словарю АОТ открыта и реализована как Rake-задача rake evaluate.
Будь я автором библиотеки на C++, я бы сделал два тестовых проекта.

Один, на Google Test, будет демонстрировать работу каждого из правил. Для этого будет запускаться «расширенная» версия функции, а затем проверка, что сработало именно это правило.

Второй, простой консольный, будет брать информацию из большого списка CSV и проверять, что всё работает.
Библиотека супер.
Думаю, на днях (в крайнем случае на след. выходных) попробую портировать на C#/.NET
Отпишу в комментарии по результатам.
Спасибо! Буду рад помочь советом или ответом.
Обязательно свяжусь с вами, если возникнут вопросы.
В руби я не впервой, код довольно понятен.
Алексей Савицкий

род.
Алексея Савицкия
дат.
Алексею Савицкию
вин.
Алексея Савицкия
тво.
Алексеем Савицкием
пре.
Алексее Савицкии

Бредятина, правда?)
Полная. Особенно если учесть, что имя и фамилия перепутаны местами.
Пример неправильного склонения:

Папа-Христозопуло Васисуалий

род.
Папы-Христозопуло Васисуалия
дат.
Папе-Христозопуло Васисуалию
вин.
Папу-Христозопуло Васисуалия
тво.
Папой-Христозопуло Васисуалием
пре.
Папе-Христозопуло Васисуалии
Принято. Правильно ли я понимаю, что ожидается неизменное «Папа-Христозопуло»?
Насколько я помню, это как раз правильное поведение.
— Части составных фамилий склоняются независимо, так что рассматриваем обе части отдельно
— Иностранные фамилии мужского рода склоняются (женского — нет, так что на Василисе Папе-Христозопуло был бы сбой, но это к делу не относится :) )
— часть «Христозопуло», как и все фамилии на -о, не склоняется (см., например, www.gramota.ru/spravka/letters/?rub=rubric_482 )
— часть «Папа» — зависит от происхождения, но, если корень славянский, то склоняется.

Да и вообще, требовать 100% верной работы от лингвистического алгоритма бессмысленно. В языке есть множество неформализованных моментов, а к фамилиям это относится вдвойне.
В веб интерфейсе используется шрифт Cuprum, а с ним буквы скачут. По крайней мере Chromium/linux

Я плохо разбираюсь во фронтэнде, но не уверен, что проблема на нашей стороне. У меня под Linux в Google Chrome и Firefox всё в полном порядке.
Сайт как раз разрабатывался на Хроме в Убунте, у вас скорее проблема со сглаживанием шрифтов, которая вызывает у некоторых шрифтов артефакты. Я использую хитинг Slight и сглаживание Rgba.
Странно, но у меня такая штука только с один шрифтом — Cuprum с google fonts, сам сталкивался просто.
Там ещё проблема с Хрома/Хромиума на некоторых дистрибутивах. Он иногда не видит системные настройки сглаживания/хитинга шрифтов и использует весьма ужасные. Лечиться созданием ~/.font.config и перезапуском браузера.
Иванов Гаврило получил от Розенталя указание склоняться, а не так как сейчас.
Спасибо. Посмотрим, что можно сделать.
Вот это расклад

род.
Гади Петровича Хренова
дат.
Гаде Петровичу Хренова
вин.
Гадю Петровича Хренова
тво.
Гадей Петровичом Хренова
пре.
Гаде Петровиче Хренова
Нет. В демонстрационном интерфейсе порядок слов задаётся как ФИО. Подозреваю, что это совсем не то, что написано выше.
У вас порядок неправильный, но и при правильном порядке неправильно склоняет

род.
Хреновой Гади Петровича
дат.
Хреновой Гаде Петровичу
вин.
Хренову Гадю Петровича
тво.
Хреновой Гадей Петровичем
пре.
Хреновой Гаде Петровиче
На мой взгляд, пример некорректен. Быть может, всё-таки, имелась в виду женщина по имени Хренова Гада Петровна? С ней всё хорошо. Не бывает женщин с отчеством «Петрович».
— О, у нас сегодня романтика-свечи, масло…
— Слышь, Петрович, отойди от капота!

— Почему ты так и не предложил выйти за тебя?
— Бля, Петрович, прораб же сказал, что сменами нельзя меняться!

— Помнишь, как мы кончили одновременно?
— Бля, Петрович, помню, конечно, мы же в параллельных классах учились.

— Теперь расслабься и смотри, как я беру его в ротик и нежно отсасываю…
— Бля, Петрович, давай быстрее бензин перельем и поедем уже!

— А засунь в обе дырочки по пальчику…
— Бля, Петрович, это же розетка, хочешь, чтобы меня током пиздануло?!

— Да я отвечаю это вкусно! В Таиланде все их едят. «Жареные гусеницы» называется!
— Бля, Петрович, и на чем теперь трактор то будет ездить?!

— Ой! посмотри как у меня сосочки затвердели! Это наверно от холода…
— Бля, Петрович, да мне похуй, давай работать уже!

— Что ты со мной делаешь? Опять тушь потекла…
— Бля, Петрович, с твоими кривыми руками мы чертеж никогда не закончим!

— Может, еще немножко поваляемся? Я сейчас без трусиков…
— Бля, Петрович, подымайся, тельник в зубы и бегом! Магистраль прорвало!
Спасибо за прекрасную библиотеку.

Русскоязычные комментарии на GitHub режут глаз.
Пожалуйста, пользуйтесь. Увы, русский язык в комментариях к коду — не единственная проблема, но самая заметная.
Я в Ruby новичок, бывает очень интересно читать чужой код и разбираться, что к чему. По вашему коду возник вопрос.

Посмотрел структуру основного файла. Не могу понять, почему именно так сделано:

Пол можно определять синглтон-классом: Petrovich.detect_gender('Ильич'). Для всего остального требуется создать инстанс, но стиль работы с этим инстансом точно такой же, как с синглтоном: Petrovich.new.firstname('Кузьма', :dative).

Не логичнее ли было бы либо всё сделать синглтоном (при этом пол можно принимать опциональным аргументом), либо создавать инстанс индивидуально для фамилии? Например, как-то так:

user = Petrovich.new('Томас Ильич Эдисон')
puts user.fullname(:dative)   # => Томаса Ильича Эдисона
puts user.middlename(:dative) # => Ильича
puts user.to_s                # => Томас Ильич Эдисон
UFO just landed and posted this here
Это сделано, чтобы учитывать ФИО как отдельные строки.
Я не понимаю. Объясните, пожалуйста, на примере и в сравнении с моим примером.
Вот например, когда нужно просклонять только имя:

p = Petrovich.new(:male)
p.firstname('Пётр', :dative)  # => Петру
Ну, и чем это лучше метода класса?

Petrovich.firstname('Пётр', :dative, :male)  # => Петру

Зачем создавать инстанс? Я так понимаю, у вас будет болтаться два инстанса: для мужского и женского родов, и непонятно, какие сущности они представляют и зачем их держать в памяти.
Мне нравится такой вариант. Bonch, что скажешь?
Комментарии в коде специально по-русски писал. Библиотека ведь только для русскоязычных. Глупо было бы писать комментарии на английском.
Мне кажется, что это не совсем правильно. Комментарии на русском лучше оставить только в файле с правилами для русского языка.
Ничуть не глупо. Английский — международный язык общения. А для программиста английский — единый язык любой документации.

Представьте, фрилансите вы, и вам заказчик дает библиотеку с документацией на болгарском. «Ну окуеть теперь!» скажете вы и будете правы.
Библиотека ведь только для русскоязычных.


Ну, почему. Какой-нибудь англоязычный сервис пытается писать по-русски, но коверкает имена. Можно было бы им написать: «Hey, guys, stop abusing Russian language. You can use insanely great Petrovich library after all.» Но там комментарии на русском.
использовал её в своём проекте. ниразу не подвела.
багрепорт: не учитываются запятые в исходной строке.
Пример: Бердымухамедов, Гурбангулы Мяликгулыевич

род. Бердымухамедов, Гурбангулы Мяликгулыевича

Если убрать запятую:
род. Бердымухамедова Гурбангулы Мяликгулыевича
Я не в теме, но может быть лучше сделать склонение по выборке из базы «88 314 примеров»?
Попробовал Джона Леннона. Творительный получался либо Джоным Ленноном, либо Ленноным Джоном. Какой-то Ленноный Джон получается :) Справедливости ради — имя не русское.
РодЛеннона Джона
дат.
Леннону Джону
вин.
Леннона Джона
тво.
Ленноным Джоном
пре.
Ленноне Джоне
Спасибо за отчёт. Здесь с нашей стороны будет проще добавить исключение. Вообще, не помешала бы выгруженная откуда-нибудь статистика по фамилиям. Это поможет уточнить правила.
Персонаж комедии «Иван Васильевич меняет профессию» Бунша Иван Васильевич:

род. Буншы Ивана Васильевича — должно быть Бунши.
твор. Буншой Иваном Васильевичем — должно быть Буншей.

Остальные верные.
Вы простите если пропустил, но все же спрошу, как используется surnames.tsv с базой фамилий?
Во время работы — никак. Это таблица с эталонами для проведения автоматической оценки при помощи rake evaluate.
UFO just landed and posted this here
Несмотря на то, что алгоритм реально работает — название сайта наиболее полно отражает впечатление от кода.
Вы не понимаете, это же старая школа! =)

PS Ссылка пришлась в тему холивара, где я отстаивал точку зрения, что 1С почти необратимо формирует дурной стиль программирования у человека, и он теряет способность понять, чем такой код плох.
UFO just landed and posted this here
Некая девушка ломает отображение на сайте. Имя ей Иванова-Петрова-Водкина Евлампия Понтелеевна!
UFO just landed and posted this here
В Корее довольно часто встречается фамилия «Ё», происходит она из китайского языка и при написании иероглифами делится на три клана. В 2000 году найдено 75,196 однофамильцев. Помимо Кореи буква «Ё» выступает в роли фамилии и в России, в переводе с французского означает «глаза». В России она считается очень редкой, насчитывается всего три ее носителя.
samogo.net/articles.php?id=2113
Да, можно добавить рядом.
А зачем добавлять? Все однобуквенные не склоняются же.
Исправим. Вот только наберем побольше фидбэка и займемся выпуском следующей версии.
Мне нужно было единоразово просклонять названия товаров, и я, подглядывая в исходники петровича (не без ctrl-c, ctrl-v), сделал сыроватый гем для склонения заголовков и определительных словосочетаний — github.com/estum/russian_inflect.

С моими задачами гем справился, но есть немало слов, которые он просклоняет неправильно (например, слово «палец»).
Я пока слабо представляю, как внести в rules.yml все правила из ru.wiktionary.org/w/index.php?oldid=2775434, чтобы они не противоречили друг другу и чтобы не пришлось явно указывать род и число. Нужно хотя бы забить в тесты примеры из викисловаря и потом пытаться подогнать результат, но, увы, на это пока нет свободного времени.

Пардоньте за некошерные ссылки.
Отличная работа! Увы, задача склонения в общем виде достаточно нетривиальна. Для этого существуют специальные анализаторы, лемматизаторы и «склоняторы». Сегодня для Ruby нет даже близкого аналога pymorphy2, а я со своим Myaso всё никак не сдвинусь с мёртвой точки, потому что практически нет времени на программирование.
Склонятор — всё, и довольно давно. Соответственно, yandex_inflect тоже не работает. Я его первым делом попробовал, перед тем как начать неистово кодить свой гем.
Увы, Яндекс отключил свой сервис достаточно давно.
Очень похоже на алгоритмы библиотеки padeg, про которую я писал тут в прошлом году (а это тесты: test-rlab.rhcloud.com/). Только там все правила в коде, а тут — в «таблицах», и это очень хорошо: такую библиотеку проще портировать. Если говорить о портируемости, то не мешало бы еще бы поработать над форматом таблиц, какой-нибудь общеупотребимый формат, тот же xml или json.
А чего пока нет — это склонения китайских ФИО, плюс склонения должностей и подразделений.
Авторы, примете пожертвования в виде исходных кодов?
Конечно, присоединяйтесь! Для портируемости в среднесрочной перспективе лучше использовать JSON. Изначально Petrovich не задумывался как инструмент для склонения должностей и подразделений, но было бы интересно посмотреть на реализацию. Если там можно обойтись относительно простыми правилами без использования чего-то хитрого или нетривиального, то было бы круто.
Не надо менять формат, YAML привычен в руби, для таких вещей очень удобен и конвертируется в xml или json легким движением руки.
А вообще это хитрый способь узнать настоящие фамилии хабрапользователей))
Не буду перечислять все недоработки, приведу одну:
род. Кима Ира-Сена

www.gramota.ru/slovari/info/ag/sklon/
5.2. В составных именах и фамилиях вьетнамских, корейских, бирманских, камбоджийских, китайских и др. склоняется последняя часть: Нгуен Тхи Бинь, Нгуен Тхи Биня [эн] (вьетнамск. гос. деятель); КИМ ЁН НАМ, Ким Ён Нама (сев.-кор. гос. деятель); 〈…〉
И этому правилу даже есть объяснение. Дело в том, что первая часть таких имён (по крайней мере корейских) — это фамилия (Ким), которая не склоняется. А _две_ остальные части (Ир Сен) — это имя (которое склоняется). И в принципе вполне корректно (хотя и непривычно) записывать в таком виде — Ким Ирсен, Ким Ченыр и т.д.
Есть недоработки с окончаниями фамилий в творительном падеже "- ем" vs "-ём".
Примеры: Кромвель — Кромвелем, Коваль-Ковалем (-нормально).
Но: Костыль- Костылем (-не корректно), должно быть — Костылём.
Тут, наверное, зависит от ударения:
Кост'ыль — Костылём
К'остыль — К'остылем
Вроде не обязательно использовать «ё» в окончаниях при склонении, а как правильно прочитать окончание и так понятно [*]. Лучше в таких случаях склонять везде с «е», чем пропустить какое-нибудь исключение и получить неправильную «ё». Короче, имхо, это несущественно.

* Задумался над творитерным падежом слова «холуй» — я бы произнёс «холуем», но в викисловаре указано «холуём».
И так же с другими словами оканчивающимися на «уй» ;)
Вот волшебный код на 1с. Я не понимаю, как он работает, но работает:

слабонервным не смотреть
// Функция для склонения одного слова!!!
// z1 - само слово
// z2 - номер падежа
// z3 - пол
// z4 - 1-склонять как фамилию, 2-имя, 3-отчество
Функция ПадежС(z1,Знач z2=2,Знач z3="*",z4=0) Экспорт
	z5=Найти(z1,"-");
	z6=?(z5=0,"","-"+ПадежС(Сред(z1,z5+1,СтрДлина(z1)-z5+1),z2,z3,z4));
	z1=НРег(?(z5=0,z1,Лев(z1,z5-1)));
	z7=Прав(z1,3);z8=Прав(z7,2);z9=Прав(z8,1);
	z5=СтрДлина(z1);
	za=Найти("ая ия ел ок яц ий па да ца ша ба та га ка",z8);
	zb=Найти("аеёийоуэюяжнгхкчшщ",Лев(z7,1));
	zc=Макс(z2,-z2);
	zd=?(za=4,5,Найти("айяь",z9));
	zd=?((zc=1)или(z9=".")или((z4=2)и(Найти("оиеу"+?(z3="ч","","бвгджзклмнпрстфхцчшщъ"),z9)>0))или((z4=1)и(Найти("мия мяэ лия кия жая лея",z7)>0)),9,?((zd=4)и(z3="ч"),2,?(z4=1,?(Найти("оеиую",z9)+Найти("их ых аа еа ёа иа оа уа ыа эа юа яа",z8)>0,9,?(z3<>"ч",?(za=1,7,?(z9="а",?(za>18,1,6),9)),?(((Найти("ой ый",z8)>0)и(z5>4)и(Найти("опой вбой",Прав(z1,4))=0))или((zb>10)и(za=16)),8,zd))),zd)));
	ze=Найти("лец нёк вей бей дец пец мец нец рец вец аец иец ыец бер",z7);
	zf=?((zd=8)и(zc<>5),?((zb>15)или(Найти("жий ний",z7)>0),"е","о"),?(z1="лев","ьв",?((Найти("аеёийоуэюя",Сред(z1,z5-3 ,1))=0)и((zb>11)или(zb=0))и(ze<>49),"",?(za=7,"л",?(za=10,"к",?(za=13,"йц",?(ze=0,"",?(ze<16,"ь"+?(ze=1,"ц",?(ze=5,"к","")),?(ze<41,"ц",?(ze<53,"йц","р"))))))))));
	zf=?((zd=9)или((z4=3)и(Прав(z1,1)="ы")),z1,Лев(z1,z5-?((zd>6)или(zf<>""),2,?(zd>0,1,0)))+zf+СокрП(Сред("а у а "+?((z8="ич")или(z8="ыш"),"е",?((z8="ов")or(z8="ин"),"ы","о"))+"ме "+?(Найти("гжкхш",Лев(z8,1))>0,"и","ы")+" е у ойе я ю я ем"+?(za=16,"и","е")+" и е ю ейе и и ь ьюи и и ю ейи ойойу ойойойойуюойойгомуго"+?((zf="е")или(za=16)или((zb>12)и(zb<16)),"и","ы")+"мм",10*zd+2*zc-3,2)));
	Возврат ?(""=z1,"",?(z4>0,ВРег(Лев(zf,1))+?((z2<0)и(z4>1),".",Сред(zf,2)),zf)+z6);
КонецФункции

//_____________________________________________________________________________
// z1 - фамилия имя отчество например Железняков Юрий Юрьевич
// z2 - Падеж ( по  умолчанию = 2 - родительный)
// 2 - родительный  ( нет кого?    ) Железнякова Юрия Юрьевича
// 3 - дательный    ( кому?        ) Железнякову Юрию Юрьевичу
// 4 - винительный  ( вижу кого?   ) Железнякова Юрия Юрьевича
// 5 - творительный ( кем?         ) Железняковым Юрием Юрьевичем
// 6 - предложный   ( о ком?       ) Железнякове Юрии Юрьевиче
// Если задать Z2 меньше 0, то на выходе получим от -1=Железняков Ю. Ю. до -6=Железнякове Ю. Ю.
// z3 - параметр Пол может не указываться, но при наличии фамилий с
// инициалами точное определение пола невозможно, поэтому предлагается задавать пол этим
// параметром  1 - мужской 2 - женский
// ДЛЯ СКЛОНЕНИЯ ПРОФЕССИЙ ИСПОЛЬЗУЙТЕ ФУНКЦИЮ ПАДЕЖП И БУДЕТ ВАМ СЧАСТЬЕ!
// ---------------------------------------------------------------------------------------
// Бибик Галушка Цой Николайчик Наталия Петровна Герценберг Кривошей Капица-Метелица
// Если Падеж(Фио ,1 ,3),       то на выходе получим Фамилия Имя Отчество и т.д.
// Если Падеж(Фио ,1 ,3,"1" ),  то                   Фамилия
// Если Падеж(Фио ,1 ,3,"2" ),  то                   Имя
// Если Падеж(Фио ,1 ,3,"3" ),  то                   Отчество
// Если Падеж(Фио, 1 ,3,"12" ), то                   Фамилия Имя
// Если Падеж(Фио, 1 ,3,"23" ), то                   Имя Отчество
// Если Падеж(Фио,-1 ,3,"231" ),то                   И. О. Фамилия
// Если Падеж(Фио,-1 ,3,"23" ), то                   И. О.
// 10-11-2003 3-20
Функция Падеж(z1,z2=2,z3=3,z4="123",z5=1) Экспорт
	z6=Нрег(Прав(СокрП(z1),4));
	z7=Прав(z6,1);
	Возврат?(z5<4,Падеж(СокрЛП(СтрЗаменить(Сред(z1,Найти(z1+" "," ")+1),".",". ")),z2,z3,СтрЗаменить(z4,z5,ПадежС(?((z5=3)и(z7="ы"),z1,Лев(z1,Найти(z1+" "," ")-1)),z2,Сред("ча"+z7,?(z3=3,?(z6="оглы",1,?(z6="кызы",1,3)),z3),1),z5)+" "),z5+1),z4);
КонецФункции

Функция ПадежП(Знач z1,Знач z2,z3=0) Экспорт
	z1=СокрЛП(z1);z4=Найти(z1+" "," ")+1;z5=Лев(z1,z4-2);z6=Прав(z5,2);
	z7=?((Найти("ая ий ый",z6)>0)и(Найти("ющий нный",Сред(z1,z4-5,4))=0)и(z3=0),"1","*");
	Возврат НРег(?((z6="ая")или(Прав(z6,1)="а"),ПадежС(z5,z2,z7,1)+" "+ПадежС(Сред(z1,z4),z2),ПадежС(z5,z2,"ч",1)+?((z6="ий")и(Найти(z1," ")=0),""," "+?(z7="1",ПадежП(Сред(z1,z4),z2,Число(z7)),Сред(z1,z4)))));
КонецФункции


Имя «Павел» просклонял в творительном падеже как «Павелом».
В Python для подобных вещей давно использую pymorphy.
Кстати, было бы гораздо интереснее, если бы описали в общих словах алгоритмы, на которых это всё основывается.
У меня получилось без особых проблем портировать библиотеку на javascript (nodejs). Работает с вашим набором правил yml.
> require('petrovich').firstname('Никита', 'male', 'dative');
Никите
> require('petrovich').middlename('Александрович', 'male', 'dative')
Александровичу

Если это кому-нибудь нужно, проведу небольшой рефакторинг, оформлю в виде npm пакета, и, скорее всего, даже сделаю скрипт для браузеров, и выложу все это на github.
Пока писал комментарий, вы меня опередили :)
Отличная штука, портировал на JavaScript: http://github.com/deNULL/petrovich-js.

Для демо у вас страничку утащил, извините если что :)

Использовать можно примерно так:

<script src="lib/petrovich.js"></script>
<script src="lib/petrovich.rules.js"></script>

// Можно сразу указать ФИО так...
var ivan = new Petrovich("Иванов", "Иван", "Иванович", Petrovich.MALE);
var ivanName = ivan.lastName(Petrovich.GENITIVE);

// ...или так
var gadya = new Petrovich({ firstName: "Гадя", middleName: "Петрович", lastName: "Хренова" }, Petrovich.FEMALE);

// Или не указывать вовсе, как в исходной либе (кстати, пол тоже опционален)
var petya = new Petrovich(Petrovich.ANDROGYNOUS);
var petyaName = petya.firstName("Петя", Petrovich.DATIVE);

// А можно и вовсе не создавать объект
var otherName = Petrovich.lastName("Петров", Petrovich.ACCUSATIVE, Petrovich.MALE); 
Класс. Добавим ссылку с нашего репо.
Почему я попадаю на эмульгатор DCPU-16, когда жму Enter?
Начал портировать на .NET как и обещал, вечером дам ссылку на гитхаб. Пока что все просто в лоб переписал. Надо еще порефакторить и навести красоту
Пожалуйста, обратите внимание, что оригинальный репозиторий переехал на новый адресgithub.com/petrovich/petrovich-ruby.

Теперь мы поддерживаем несколько официальных портов, список которых представлен на странице организации github.com/petrovich/petrovich.
UFO just landed and posted this here
Спасибо за комментарий!

Эталонным поведением считается поведение Ruby-версии библиотеки, так сложилось исторически. Имеется централизованный репозиторий с правилами, которые должны использоваться всеми портами. Если этого не происходит, то нужно обратиться к автору порта. Если выявляются ошибки в правилах, то мы стараемся исправить их по мере информирования.

Сейчас PHP-версия поддерживается difiso. Надеюсь, он увидит этот вопрос.
UFO just landed and posted this here
UFO just landed and posted this here
Похоже в Петровиче нужно правила подкорректировать. Посмотрел на тест — там вроде однотипные ошибки — фамилии оканчивающиеся на ке/ре/ом неправильно склоняются. Хотя фамилия Дюссар в вашем примере неправильно склоняется, но здесь — petrovich.rocketscience.it/ правильно. Странно.
UFO just landed and posted this here
А почему пол задается через конструктор? По моему, не слишком удобно.

PS. Когда я что-то подобное писал, я не справился с двумя фамилиями акционеров АНТК Туполева — Заяц и Ручей.
Какие есть решения для определения имени в ФИО?
Sign up to leave a comment.

Articles