Комментарии 144
Не хватает определение пола ещё по имени, там точность будет меньше, но тоже полезно.
Да, это было бы полезно.
Пол лучше определять по отчеству — славянские отчества у женщин кончаются на «а», у мужчин, напротив — никогда не кончаются на «а».
Писал лет 10 назад библиотеку склонений ФИО в родительный падеж, исключение — ФИО содержащие «оглы/кызы» — собственно оглы у мужчин, кызы — у женщин, так что тоже 100% попадание в пол.
По фамилии — такое-же правило, у женщин всегда «а», кроме несклоняемых фамилий. Но тут и человек не угадает по фамилии :-)
Писал лет 10 назад библиотеку склонений ФИО в родительный падеж, исключение — ФИО содержащие «оглы/кызы» — собственно оглы у мужчин, кызы — у женщин, так что тоже 100% попадание в пол.
По фамилии — такое-же правило, у женщин всегда «а», кроме несклоняемых фамилий. Но тут и человек не угадает по фамилии :-)
Короче, надо сделать определение пола по всем трём параметрам. Тогда точность максимальная будет.
В настоящее время пол определяется по отчеству при помощи очень простой эвристики.
— А ты помнишь свое отчество?©
— Только последние три буквы...
UPD. Еще бы не возникла эта ссылка в каментах.
В одном из моих приложений есть необходимость определять пол, причем отчества может и не быть, или фамилии, я просто взял у твиттера открытые словари имен (русских и иностранных), и гружу в хэш-лист, точность определения близка к 100%, за исключением сложных случаев, например, когда женская фамилия совпадает с мужским именем. Ну и скорость при использовании HashSet не будет уступать использованию вашей простой эвристики.
Клёво. Где можно посмотреть словари и результаты?
Не нашел где оригиналы лежат, выложил у себя:
Женские(рус)
Мужские(рус)
Женские(eng)
Мужские(eng)
Списки неполные, особенно иностранные, для этого случая завожу дополнительные словари, в которые помещаю сложные варианты.
Женские(рус)
Мужские(рус)
Женские(eng)
Мужские(eng)
Списки неполные, особенно иностранные, для этого случая завожу дополнительные словари, в которые помещаю сложные варианты.
Кстати, еще идея для имен без отчества:
1) определяем по словарю мужских/женских имен
2) если имя нет в словаре, ищем людей с такой же фамилией и определяем пол по ним
3) если найдено не меньше 3х, заносим имя в словарь
Пример:
Елена Иванова — имя «Елена» в словаре женское, значит женщина
Даздраперма Иванова — ищем выборку с фамилией «Иванова», смотрим пол большинства (например, 5 — женщин, 1 — ошибочно заведенный мужик), и решаем, что Даздраперма — женщина. Так как найдено больше 3х, то заносим «Даздраперма» в словарь женских имён.
1) определяем по словарю мужских/женских имен
2) если имя нет в словаре, ищем людей с такой же фамилией и определяем пол по ним
3) если найдено не меньше 3х, заносим имя в словарь
Пример:
Елена Иванова — имя «Елена» в словаре женское, значит женщина
Даздраперма Иванова — ищем выборку с фамилией «Иванова», смотрим пол большинства (например, 5 — женщин, 1 — ошибочно заведенный мужик), и решаем, что Даздраперма — женщина. Так как найдено больше 3х, то заносим «Даздраперма» в словарь женских имён.
Предлагаю более железобетонный вариант:
Пола 'androgynous' не бывает, и неопределённость можно списать на мужчин.
def detect_gender(midname)
tail = UnicodeUtils.downcase(midname[-4, 4])
if (tail[-1]=='а') or (tail=='кызы')
'female'
else
'male'
end
end
Пола 'androgynous' не бывает, и неопределённость можно списать на мужчин.
По фамилии — такое-же правило, у женщин всегда «а», кроме несклоняемых фамилий.
Иван Васильевич Бунша. Фамилия склоняется.
Иван Васильевич Бунша. Фамилия склоняется.
Я же написал — «кроме несклоняемых фамилий».
«Бунша» — несклоняемая фамилия, поэтому по одной фамилии определить нельзя никак.
«Бунша» — несклоняемая фамилия, поэтому по одной фамилии определить нельзя никак.
Склоняемая, я же написал.
Родительный: Это шляпа Бунши (не «Это шляпа Бунша»).
Дательный: Отдай книгу Бунше (не «Отдай книгу Бунша»).
Винительный: Поступила жалоба на Буншу (не «Поступила жалоба на Бунша»).
Творительный: Забор был покрашен Буншей (не «Забор был покрашен Бунша»).
Предложный: Написали статью о Бунше (не «Написали статью о Бунша»).
Собственно, по фамилии пол определить нельзя, потому что и у мужчины фамилия может заканчиваться на «а». И именно это я и иллюстрирую.
Родительный: Это шляпа Бунши (не «Это шляпа Бунша»).
Дательный: Отдай книгу Бунше (не «Отдай книгу Бунша»).
Винительный: Поступила жалоба на Буншу (не «Поступила жалоба на Бунша»).
Творительный: Забор был покрашен Буншей (не «Забор был покрашен Бунша»).
Предложный: Написали статью о Бунше (не «Написали статью о Бунша»).
Собственно, по фамилии пол определить нельзя, потому что и у мужчины фамилия может заканчиваться на «а». И именно это я и иллюстрирую.
По имени тоже можно ) Насколько помню только одно женское имя не оканчивается не на а или я.
Гадя Петрович Хренова…
UPD: Я всегда буду читать все комментарии перед тем как постить…
UPD: Я всегда буду читать все комментарии перед тем как постить…
Я, когда такое писал, определял по отчеству. У отчеств разнообразие было меньше.
Неплохо было бы веб-сервисом сделать, например.
Спасибо, поправим.
Верно. Примеры: Синих, Больных.
Вообще, надо сделать дополнительный флаг: русский/иностранец.
Пушкин → Пушкиным (русский)
Раскин → Раскином (американец)
Иванов → Ивановым (русский)
Сальхов → Сальховом (швед)
Пушкин → Пушкиным (русский)
Раскин → Раскином (американец)
Иванов → Ивановым (русский)
Сальхов → Сальховом (швед)
Безусловно, подобные флаги имели бы ценность и здорово помогали при обработки слов. Однако я не уверен, что их должен задавать конечный пользователь.
Такова, ёлки зелёные, жизнь. И Юникод так сложен, потому что сложна наша письменность.
Может быть, для isMale и isRussian придётся делать троичную логику: true/false/unknown, с угадыванием, например, по словарю.
Может быть, для isMale и isRussian придётся делать троичную логику: true/false/unknown, с угадыванием, например, по словарю.
Уже отправил в баг-трекер, у меня тоже фамилия в творительном не так склоняется (Быхун).
Библиотека несложна, «особой рубиновой магии» там вроде бы нет, и, кажется, портация на С++ должна занять день.
Сложнее будет написать юнит-тесты.
Сложнее будет написать юнит-тесты.
Будь я автором библиотеки на C++, я бы сделал два тестовых проекта.
Один, на Google Test, будет демонстрировать работу каждого из правил. Для этого будет запускаться «расширенная» версия функции, а затем проверка, что сработало именно это правило.
Второй, простой консольный, будет брать информацию из большого списка CSV и проверять, что всё работает.
Один, на Google Test, будет демонстрировать работу каждого из правил. Для этого будет запускаться «расширенная» версия функции, а затем проверка, что сработало именно это правило.
Второй, простой консольный, будет брать информацию из большого списка CSV и проверять, что всё работает.
Библиотека супер.
Думаю, на днях (в крайнем случае на след. выходных) попробую портировать на C#/.NET
Отпишу в комментарии по результатам.
Думаю, на днях (в крайнем случае на след. выходных) попробую портировать на C#/.NET
Отпишу в комментарии по результатам.
Алексей Савицкий
род.
Алексея Савицкия
дат.
Алексею Савицкию
вин.
Алексея Савицкия
тво.
Алексеем Савицкием
пре.
Алексее Савицкии
Бредятина, правда?)
род.
Алексея Савицкия
дат.
Алексею Савицкию
вин.
Алексея Савицкия
тво.
Алексеем Савицкием
пре.
Алексее Савицкии
Бредятина, правда?)
Пример неправильного склонения:
Папа-Христозопуло Васисуалий
род.
Папы-Христозопуло Васисуалия
дат.
Папе-Христозопуло Васисуалию
вин.
Папу-Христозопуло Васисуалия
тво.
Папой-Христозопуло Васисуалием
пре.
Папе-Христозопуло Васисуалии
Папа-Христозопуло Васисуалий
род.
Папы-Христозопуло Васисуалия
дат.
Папе-Христозопуло Васисуалию
вин.
Папу-Христозопуло Васисуалия
тво.
Папой-Христозопуло Васисуалием
пре.
Папе-Христозопуло Васисуалии
Принято. Правильно ли я понимаю, что ожидается неизменное «Папа-Христозопуло»?
Насколько я помню, это как раз правильное поведение.
— Части составных фамилий склоняются независимо, так что рассматриваем обе части отдельно
— Иностранные фамилии мужского рода склоняются (женского — нет, так что на Василисе Папе-Христозопуло был бы сбой, но это к делу не относится :) )
— часть «Христозопуло», как и все фамилии на -о, не склоняется (см., например, www.gramota.ru/spravka/letters/?rub=rubric_482 )
— часть «Папа» — зависит от происхождения, но, если корень славянский, то склоняется.
Да и вообще, требовать 100% верной работы от лингвистического алгоритма бессмысленно. В языке есть множество неформализованных моментов, а к фамилиям это относится вдвойне.
— Части составных фамилий склоняются независимо, так что рассматриваем обе части отдельно
— Иностранные фамилии мужского рода склоняются (женского — нет, так что на Василисе Папе-Христозопуло был бы сбой, но это к делу не относится :) )
— часть «Христозопуло», как и все фамилии на -о, не склоняется (см., например, www.gramota.ru/spravka/letters/?rub=rubric_482 )
— часть «Папа» — зависит от происхождения, но, если корень славянский, то склоняется.
Да и вообще, требовать 100% верной работы от лингвистического алгоритма бессмысленно. В языке есть множество неформализованных моментов, а к фамилиям это относится вдвойне.
В веб интерфейсе используется шрифт Cuprum, а с ним буквы скачут. По крайней мере Chromium/linux


Я плохо разбираюсь во фронтэнде, но не уверен, что проблема на нашей стороне. У меня под Linux в Google Chrome и Firefox всё в полном порядке.
Сайт как раз разрабатывался на Хроме в Убунте, у вас скорее проблема со сглаживанием шрифтов, которая вызывает у некоторых шрифтов артефакты. Я использую хитинг Slight и сглаживание Rgba.
Там ещё проблема с Хрома/Хромиума на некоторых дистрибутивах. Он иногда не видит системные настройки сглаживания/хитинга шрифтов и использует весьма ужасные. Лечиться созданием ~/.font.config и перезапуском браузера.
Иванов Гаврило получил от Розенталя указание склоняться, а не так как сейчас.
Вот это расклад
род.
Гади Петровича Хренова
дат.
Гаде Петровичу Хренова
вин.
Гадю Петровича Хренова
тво.
Гадей Петровичом Хренова
пре.
Гаде Петровиче Хренова
род.
Гади Петровича Хренова
дат.
Гаде Петровичу Хренова
вин.
Гадю Петровича Хренова
тво.
Гадей Петровичом Хренова
пре.
Гаде Петровиче Хренова
Нет. В демонстрационном интерфейсе порядок слов задаётся как ФИО. Подозреваю, что это совсем не то, что написано выше.
У вас порядок неправильный, но и при правильном порядке неправильно склоняет
род.
Хреновой Гади Петровича
дат.
Хреновой Гаде Петровичу
вин.
Хренову Гадю Петровича
тво.
Хреновой Гадей Петровичем
пре.
Хреновой Гаде Петровиче
род.
Хреновой Гади Петровича
дат.
Хреновой Гаде Петровичу
вин.
Хренову Гадю Петровича
тво.
Хреновой Гадей Петровичем
пре.
Хреновой Гаде Петровиче
На мой взгляд, пример некорректен. Быть может, всё-таки, имелась в виду женщина по имени Хренова Гада Петровна? С ней всё хорошо. Не бывает женщин с отчеством «Петрович».
— О, у нас сегодня романтика-свечи, масло…
— Слышь, Петрович, отойди от капота!
— Почему ты так и не предложил выйти за тебя?
— Бля, Петрович, прораб же сказал, что сменами нельзя меняться!
— Помнишь, как мы кончили одновременно?
— Бля, Петрович, помню, конечно, мы же в параллельных классах учились.
— Теперь расслабься и смотри, как я беру его в ротик и нежно отсасываю…
— Бля, Петрович, давай быстрее бензин перельем и поедем уже!
— А засунь в обе дырочки по пальчику…
— Бля, Петрович, это же розетка, хочешь, чтобы меня током пиздануло?!
— Да я отвечаю это вкусно! В Таиланде все их едят. «Жареные гусеницы» называется!
— Бля, Петрович, и на чем теперь трактор то будет ездить?!
— Ой! посмотри как у меня сосочки затвердели! Это наверно от холода…
— Бля, Петрович, да мне похуй, давай работать уже!
— Что ты со мной делаешь? Опять тушь потекла…
— Бля, Петрович, с твоими кривыми руками мы чертеж никогда не закончим!
— Может, еще немножко поваляемся? Я сейчас без трусиков…
— Бля, Петрович, подымайся, тельник в зубы и бегом! Магистраль прорвало!
— Слышь, Петрович, отойди от капота!
— Почему ты так и не предложил выйти за тебя?
— Бля, Петрович, прораб же сказал, что сменами нельзя меняться!
— Помнишь, как мы кончили одновременно?
— Бля, Петрович, помню, конечно, мы же в параллельных классах учились.
— Теперь расслабься и смотри, как я беру его в ротик и нежно отсасываю…
— Бля, Петрович, давай быстрее бензин перельем и поедем уже!
— А засунь в обе дырочки по пальчику…
— Бля, Петрович, это же розетка, хочешь, чтобы меня током пиздануло?!
— Да я отвечаю это вкусно! В Таиланде все их едят. «Жареные гусеницы» называется!
— Бля, Петрович, и на чем теперь трактор то будет ездить?!
— Ой! посмотри как у меня сосочки затвердели! Это наверно от холода…
— Бля, Петрович, да мне похуй, давай работать уже!
— Что ты со мной делаешь? Опять тушь потекла…
— Бля, Петрович, с твоими кривыми руками мы чертеж никогда не закончим!
— Может, еще немножко поваляемся? Я сейчас без трусиков…
— Бля, Петрович, подымайся, тельник в зубы и бегом! Магистраль прорвало!
Спасибо за прекрасную библиотеку.
Русскоязычные комментарии на GitHub режут глаз.
Русскоязычные комментарии на GitHub режут глаз.
Пожалуйста, пользуйтесь. Увы, русский язык в комментариях к коду — не единственная проблема, но самая заметная.
Я в Ruby новичок, бывает очень интересно читать чужой код и разбираться, что к чему. По вашему коду возник вопрос.
Посмотрел структуру основного файла. Не могу понять, почему именно так сделано:
Пол можно определять синглтон-классом:
Не логичнее ли было бы либо всё сделать синглтоном (при этом пол можно принимать опциональным аргументом), либо создавать инстанс индивидуально для фамилии? Например, как-то так:
Посмотрел структуру основного файла. Не могу понять, почему именно так сделано:
Пол можно определять синглтон-классом:
Petrovich.detect_gender('Ильич')
. Для всего остального требуется создать инстанс, но стиль работы с этим инстансом точно такой же, как с синглтоном: Petrovich.new.firstname('Кузьма', :dative)
.Не логичнее ли было бы либо всё сделать синглтоном (при этом пол можно принимать опциональным аргументом), либо создавать инстанс индивидуально для фамилии? Например, как-то так:
user = Petrovich.new('Томас Ильич Эдисон')
puts user.fullname(:dative) # => Томаса Ильича Эдисона
puts user.middlename(:dative) # => Ильича
puts user.to_s # => Томас Ильич Эдисон
Это сделано, чтобы учитывать ФИО как отдельные строки.
Я не понимаю. Объясните, пожалуйста, на примере и в сравнении с моим примером.
Вот например, когда нужно просклонять только имя:
p = Petrovich.new(:male)
p.firstname('Пётр', :dative) # => Петру
Комментарии в коде специально по-русски писал. Библиотека ведь только для русскоязычных. Глупо было бы писать комментарии на английском.
Мне кажется, что это не совсем правильно. Комментарии на русском лучше оставить только в файле с правилами для русского языка.
Ничуть не глупо. Английский — международный язык общения. А для программиста английский — единый язык любой документации.
Представьте, фрилансите вы, и вам заказчик дает библиотеку с документацией на болгарском. «Ну окуеть теперь!» скажете вы и будете правы.
Представьте, фрилансите вы, и вам заказчик дает библиотеку с документацией на болгарском. «Ну окуеть теперь!» скажете вы и будете правы.
Библиотека ведь только для русскоязычных.
Ну, почему. Какой-нибудь англоязычный сервис пытается писать по-русски, но коверкает имена. Можно было бы им написать: «Hey, guys, stop abusing Russian language. You can use insanely great Petrovich library after all.» Но там комментарии на русском.
Оу, уже хочу портировать на PHP :)
Было бы любопытно сравнить с этой библиотекой
багрепорт: не учитываются запятые в исходной строке.
Пример: Бердымухамедов, Гурбангулы Мяликгулыевич
род. Бердымухамедов, Гурбангулы Мяликгулыевича
Если убрать запятую:
род. Бердымухамедова Гурбангулы Мяликгулыевича
Пример: Бердымухамедов, Гурбангулы Мяликгулыевич
род. Бердымухамедов, Гурбангулы Мяликгулыевича
Если убрать запятую:
род. Бердымухамедова Гурбангулы Мяликгулыевича
Я не в теме, но может быть лучше сделать склонение по выборке из базы «88 314 примеров»?
Попробовал Джона Леннона. Творительный получался либо Джоным Ленноном, либо Ленноным Джоном. Какой-то Ленноный Джон получается :) Справедливости ради — имя не русское.
РодЛеннона Джона
дат.
Леннону Джону
вин.
Леннона Джона
тво.
Ленноным Джоном
пре.
Ленноне Джоне
РодЛеннона Джона
дат.
Леннону Джону
вин.
Леннона Джона
тво.
Ленноным Джоном
пре.
Ленноне Джоне
Спасибо за отчёт. Здесь с нашей стороны будет проще добавить исключение. Вообще, не помешала бы выгруженная откуда-нибудь статистика по фамилиям. Это поможет уточнить правила.
Вы простите если пропустил, но все же спрошу, как используется surnames.tsv с базой фамилий?
Некая девушка ломает отображение на сайте. Имя ей Иванова-Петрова-Водкина Евлампия Понтелеевна!
Одобряю
Спасибо, исправим.
Готово.
В Корее довольно часто встречается фамилия «Ё», происходит она из китайского языка и при написании иероглифами делится на три клана. В 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, чтобы они не противоречили друг другу и чтобы не пришлось явно указывать род и число. Нужно хотя бы забить в тесты примеры из викисловаря и потом пытаться подогнать результат, но, увы, на это пока нет свободного времени.
Пардоньте за некошерные ссылки.
С моими задачами гем справился, но есть немало слов, которые он просклоняет неправильно (например, слово «палец»).
Я пока слабо представляю, как внести в rules.yml все правила из ru.wiktionary.org/w/index.php?oldid=2775434, чтобы они не противоречили друг другу и чтобы не пришлось явно указывать род и число. Нужно хотя бы забить в тесты примеры из викисловаря и потом пытаться подогнать результат, но, увы, на это пока нет свободного времени.
Пардоньте за некошерные ссылки.
Отличная работа! Увы, задача склонения в общем виде достаточно нетривиальна. Для этого существуют специальные анализаторы, лемматизаторы и «склоняторы». Сегодня для Ruby нет даже близкого аналога pymorphy2, а я со своим Myaso всё никак не сдвинусь с мёртвой точки, потому что практически нет времени на программирование.
Я когда-то пользовался Яндекс склонятором, вот даже гем есть https://github.com/yaroslav/yandex_inflect
Очень похоже на алгоритмы библиотеки padeg, про которую я писал тут в прошлом году (а это тесты: test-rlab.rhcloud.com/). Только там все правила в коде, а тут — в «таблицах», и это очень хорошо: такую библиотеку проще портировать. Если говорить о портируемости, то не мешало бы еще бы поработать над форматом таблиц, какой-нибудь общеупотребимый формат, тот же xml или json.
А чего пока нет — это склонения китайских ФИО, плюс склонения должностей и подразделений.
Авторы, примете пожертвования в виде исходных кодов?
А чего пока нет — это склонения китайских ФИО, плюс склонения должностей и подразделений.
Авторы, примете пожертвования в виде исходных кодов?
Конечно, присоединяйтесь! Для портируемости в среднесрочной перспективе лучше использовать JSON. Изначально Petrovich не задумывался как инструмент для склонения должностей и подразделений, но было бы интересно посмотреть на реализацию. Если там можно обойтись относительно простыми правилами без использования чего-то хитрого или нетривиального, то было бы круто.
Не надо менять формат, YAML привычен в руби, для таких вещей очень удобен и конвертируется в xml или json легким движением руки.
А вообще это хитрый способь узнать настоящие фамилии хабрапользователей))
Не буду перечислять все недоработки, приведу одну:
www.gramota.ru/slovari/info/ag/sklon/
род. Кима Ира-Сена
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.
Кстати, было бы гораздо интереснее, если бы описали в общих словах алгоритмы, на которых это всё основывается.
Кстати, было бы гораздо интереснее, если бы описали в общих словах алгоритмы, на которых это всё основывается.
Для определения пола есть отличный русский гем: russian_sex от makaroni4
У меня получилось без особых проблем портировать библиотеку на javascript (nodejs). Работает с вашим набором правил yml.
Если это кому-нибудь нужно, проведу небольшой рефакторинг, оформлю в виде npm пакета, и, скорее всего, даже сделаю скрипт для браузеров, и выложу все это на github.
> require('petrovich').firstname('Никита', 'male', 'dative');
Никите
> require('petrovich').middlename('Александрович', 'male', 'dative')
Александровичу
Если это кому-нибудь нужно, проведу небольшой рефакторинг, оформлю в виде npm пакета, и, скорее всего, даже сделаю скрипт для браузеров, и выложу все это на github.
Пока писал комментарий, вы меня опередили :)
Давай!
Node.JS библиотека:
npmjs.org/package/petrovich-js
npm install petrovich-js
Для браузера делать не стал, deNULL постарался хорошо вэтом плане.
npmjs.org/package/petrovich-js
npm install petrovich-js
Для браузера делать не стал, deNULL постарался хорошо вэтом плане.
Упомянул порт на главной странице репозитория, спасибо за отличную работу.
Отличная штука, портировал на 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);
Класс. Добавим ссылку с нашего репо.
Упомянул этот порт на главной странице репозитория, спасибо за отличную работу. Мне кажется, вам стоит объединить усилия с MainNika.
Почему я попадаю на эмульгатор DCPU-16, когда жму Enter?
Начал портировать на .NET как и обещал, вечером дам ссылку на гитхаб. Пока что все просто в лоб переписал. Надо еще порефакторить и навести красоту
Пожалуйста, обратите внимание, что оригинальный репозиторий переехал на новый адрес — github.com/petrovich/petrovich-ruby.
Теперь мы поддерживаем несколько официальных портов, список которых представлен на странице организации github.com/petrovich/petrovich.
Теперь мы поддерживаем несколько официальных портов, список которых представлен на странице организации github.com/petrovich/petrovich.
Спасибо за комментарий!
Эталонным поведением считается поведение Ruby-версии библиотеки, так сложилось исторически. Имеется централизованный репозиторий с правилами, которые должны использоваться всеми портами. Если этого не происходит, то нужно обратиться к автору порта. Если выявляются ошибки в правилах, то мы стараемся исправить их по мере информирования.
Сейчас PHP-версия поддерживается difiso. Надеюсь, он увидит этот вопрос.
Эталонным поведением считается поведение Ruby-версии библиотеки, так сложилось исторически. Имеется централизованный репозиторий с правилами, которые должны использоваться всеми портами. Если этого не происходит, то нужно обратиться к автору порта. Если выявляются ошибки в правилах, то мы стараемся исправить их по мере информирования.
Сейчас PHP-версия поддерживается difiso. Надеюсь, он увидит этот вопрос.
Похоже в Петровиче нужно правила подкорректировать. Посмотрел на тест — там вроде однотипные ошибки — фамилии оканчивающиеся на ке/ре/ом неправильно склоняются. Хотя фамилия Дюссар в вашем примере неправильно склоняется, но здесь — petrovich.rocketscience.it/ правильно. Странно.
А почему пол задается через конструктор? По моему, не слишком удобно.
PS. Когда я что-то подобное писал, я не справился с двумя фамилиями акционеров АНТК Туполева — Заяц и Ручей.
PS. Когда я что-то подобное писал, я не справился с двумя фамилиями акционеров АНТК Туполева — Заяц и Ручей.
Какие есть решения для определения имени в ФИО?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Petrovich просклоняет русские имена