NameCaseLib. Склонение фамилии, имени и отчества
Запись от VitaliyKrivtsov размещена 04.12.2011 в 17:47
Некоторое время назад задался целью - обращение к пользователям ставить в соответствующий падеж. Выглядит красиво. Да и пользователю приятно, когда ваше приложение правильно обращается к нему по имени. Задавшись целью, я не стал писать все с нуля, а решил сначала поискать наработки других программистов.
Ни каких библиотек или хотя бы черновых наработок на ActionScript3.0 не было. Были ссылки на проекты, написанные, в большинстве, на PHP. Так же нашел небольшой скрипт со скромными возможностями, но вполне меня удовлетворяющими, на JavaScript. Автор проекта - Johnny Woo. Работает отлично. Можно было бы воспользоватся классом ExternalInterface. Но данный подход лишает возможности применять библиотеку в приложении для социальной сети ВКонтакте, если используете контейнер. В случае с iframe, то подключать вновь и вновь для последующих проектов будет не очень удобно. Так же затруднительно будет использовать в AIR или MDM Zinc. Поэтому я решил написать на чистом ActionSctipt3.0. Оставалось найти исходники подобных проектов или же написать все с нуля.
Следующий проект, который мне понравился, был на PHP - NameCaseLib. Библиотека распространяется под лицензией MIT или GPL Version 2, что не могло не порадовать. К тому же есть отличная документация по использованию библиотеки, также исходники документированы. Кроме русских склоняет еще и украинские фамилии. Уникальная особенность состоит в том, что библиотека содержит одинаковые методы для работы с ФИО на русском и украинском языках. То есть все правила были вынесены в классы NameCaseRu и NameCaseUa, унаследованные от NCLNameCaseCore, который и отвечает за процесс склонения ФИО. Автор библиотеки - Андрей Чайка. Фреймворк изначально был написан на PHP. Так же был сделан порт на C# самим же автором. Отлично склоняет русские и украинские фамилии.
Со временем, нашел еще несколько проектов на PHP - Морфер.ру и Яндекс.Склонятор. Исходников данных проектов не было. Яндекс.Склонятор - веб-сервис для разработчиков и поэтому получить результаты склонения можно было только по запросу. Морфер.ру является проектом коммерческим, хотя тоже есть веб-сервис, но с ограничениями. В целом, хорошие результаты по склонению как украинских так и русских ФИО.
Спустя неделю я переписал половину библиотеки и провел первые тесты. Библиотека справлялась с поставленной задачей. Вскоре реализовал целиком и полностью. Библиотека умеет все то, что было на данный момент в PHP, а именно:
- склонение ФИО по падежам русского и украинского языков.
- определение пола.
- работа с разными регистрами.
- форматированный вывод.
Склонение ФИО.
Основная задача данной библиотеки - склонять ФИО по заданному падежу. Все методы для склонения реализованы в классе NCLNameCaseCore. Рассмотрим метод q( fullname:String, caseNum:int = 0, gender:int = 0 ). Один параметр является обязательным - fullname. Это и есть ФИО. Может быть представлено в виде фамилии, имени, отчества или в других комбинациях. Параметр caseNum указывает на падеж, по которому будет склонено ФИО. По умолчанию равен NCL.NOM. Параметр gender указывает на пол. По умолчанию равен 0. Если не указать, то класс сам определит пол. Если не передавать параметр caseNum, будет возвращен массив со всеми склонениями. Если передать - возвращается строка с необходим падежом. Рассмотрим константы, которые используются для указания пола и падежа. Для указания пола используются следующие константы:
- NCL.MAN - мужской пол.
- NCL.WOMAN - женский пол.
- NCL.NOM - именительный/називний.
- NCL.GEN - родительный/родовий.
- NCL.DAT - дательный/давальний.
- NCL.ACC - винительный/знахідний.
- NCL.INS - творительный/орудний.
- NCL.ABL - предложный/місцевий.
package { import flash.display.Sprite; import flash.events.Event; import by.nickel.namecase.NCL; import by.nickel.namecase.NameCaseUa; import by.nickel.namecase.NameCaseRu; /** * ... * @author Vitalik Krivtsov aka Nickel */ public class Lesson1 extends Sprite { /** * @private */ private var ncua:NameCaseUa; /** * @private */ private var ncru:NameCaseRu; /** * Cons. */ public function Lesson1( ) { if ( stage ) init( ); else addEventListener( Event.ADDED_TO_STAGE, init ); } private function init( event:Event = null ):void { removeEventListener( Event.ADDED_TO_STAGE, init ); /** * Создаем обьект класса. * Теперь библиотека готова к работе. */ ncua = new NameCaseUa( ); /** * Производим склонения и выводим результат. */ trace( ncua.q('Андрій Миколайович') ); /** * Создаем обьект класса. * Теперь библиотека готова к работе. */ ncru = new NameCaseRu( ); /** * Производим склонения и выводим результат. */ trace( ncru.q('Андрей Николаевич') ); } } }
package { import by.nickel.namecase.NCL; import by.nickel.namecase.NameCaseRu; import flash.display.Sprite; import flash.events.Event; /** * * @author Vitalik Krivtsov aka Nickel */ public class Lesson2 extends Sprite { /** * @private */ private var ncru:NameCaseRu; /** * Cons. */ public function Lesson2( ) { if ( stage ) init( ); else addEventListener( Event.ADDED_TO_STAGE, init ); } /** * * @param event */ private function init( event:Event = null ):void { removeEventListener( Event.ADDED_TO_STAGE, init ); /** * */ ncru = new NameCaseRu( ); /** * Указываем падеж. */ trace( ncru.q('Андрей Николаевич', NCL.GEN) );//Андрея Николаевича /** * Явно не указываем пол. */ trace( ncru.q('Иващук') );//Иващук,Иващука,Иващуку,Иващука,Иващуком,Иващуке /** * Указываем мужской пол и не указываем падеж. */ trace( ncru.q('Иващук', NCL.NOM, NCL.MAN));//Иващук,Иващука,Иващуку,Иващука,Иващуком,Иващуке } } }
Библиотека имеет все необходимые функции для определения пола по ФИО. Данная особенность может быть полезной тогда, когда пользователь вводит только имя, но не указывает свой пол.
Определение пола реализуется при помощи метода genderDetect( fullname:String ). Где fullname строка с полным ФИО. Может быть указано фамилия и имя или по отдельности в разных комбинациях. Метод возвращает либо NCL.MAN, либо NCL.WOMAN в зависимости от пола человека.
Ниже приведены примеры использования метода genderDetect():
package { import flash.display.Sprite; import flash.events.Event; import by.nickel.namecase.NCL; import by.nickel.namecase.NameCaseRu; /** * * @author Vitalik Krivtsov aka Nickel */ public class Lesson3 extends Sprite { /** * @private */ private var ncru:NameCaseRu; /** * Cons. */ public function Lesson3( ) { if ( stage ) init( ); else addEventListener( Event.ADDED_TO_STAGE, init ); } private function init( event:Event = null ):void { removeEventListener( Event.ADDED_TO_STAGE, init ); ncru = new NameCaseRu( ); /** * */ var array:Array = ['Андрей Николаевич', 'Ирина', 'Ефиопский Аркадий Василевич', 'Мария Николаевна', 'Розумовский Илья']; var random:Number = Math.ceil( Math.random() * 4 ); /** * Выбираем случайного человека из списка. */ var person:String = array[random] as String; /** * Определяем пол. */ var gender:int = ncru.genderDetect( person ); /** * Выводим приветствие. */ trace( "Мы хотим предложить " + ncru.q( person, NCL.DAT) + "наши новые товары из категорий:" ); /** * В зависимости от пола предлагаем разные товары. */ if ( gender == NCL.MAN) { trace( "<li>Рыбалка и охота</li>\n<li>Электроника</li>\n<li>Инструменты для дома</li>" ); } else { trace( "<li>Книги о кулинарии</li>\n<li>Косметика</li>\n<li>Дом и семья</li>" ); } /** * Мы хотим предложить Ефиопскому Аркадию Василевичу наши новые товары из категорий: * <li>Рыбалка и охота</li> * <li>Электроника</li> * <li>Инструменты для дома</li> */ } } }
Не имеет значения, в каком регистре ФИО передается для склонения. Перед началом обработки каждого слова создается маска, где сохранено, какие буквы были в верхнем, а какие в нижнем регистре. После успешного склонения, регистр слов автоматически возвращается.
Ниже приведен пример:
package { import flash.display.Sprite; import flash.events.Event; import by.nickel.namecase.NCL; import by.nickel.namecase.NameCaseRu; /** * @author Vitalik Krivtsov aka Nickel */ public class Lesson4 extends Sprite { /** * @private */ private var ncru:NameCaseRu; /** * Cons. */ public function Lesson4( ) { if ( stage ) init( ); else addEventListener( Event.ADDED_TO_STAGE, init ); } private function init( event:Event = null ):void { removeEventListener( Event.ADDED_TO_STAGE, init ); ncru = new NameCaseRu( ); trace( ncru.q("АНДРЕЙ НИКОЛАЕВИЧ", NCL.GEN) );//АНДРЕЯ НИКОЛАЕВИЧА trace( ncru.q("королёв Никита ПЕТРОВИЧ", NCL.GEN) );//королёва Никиты ПЕТРОВИЧА trace( ncru.q("ПороСЁнОК ПёТР", NCL.GEN) );//ПороСЁнКА ПёТРа } } }
Библиотека отлично справляется со склонением русских и украинских ФИО. Иногда система склоняет ФИО не правильно. Чаще всего это связано с тем, что не возможно точно определить имя это, или фамилия, а так же не всегда можно правильно определить пол человека. Для того, что бы этого избежать в библиотеке есть возможность явно указать имя, фамилию, отчество, а так же пол. Этот метод с большей вероятностью правильно склонит ФИО.
Есть два способа для явного указания ФИО. В библиотеке есть метод:
ncru.qFullName( lastName:String = "", firstName:String = "", fatherName:String = "", caseNum:int = 0, gender:int = 0, format:String = "S N F" )
- S – фамилия.
- N – имя.
- F – отчество.
- "S N" - "Фамилия Имя"
- "N F" - "Имя Отчество"
- "S N F" - "Фамилия Имя Отчество"
package { import by.nickel.namecase.NCL; import by.nickel.namecase.NameCaseRu; import flash.display.Sprite; import flash.events.Event; /** * ... * @author Vitalik Krivtsov aka Nickel */ public class Lesson5 extends Sprite { /** * @private */ private var ncru:NameCaseRu; /** * Cons. */ public function Lesson5( ) { if ( stage ) init( ); else addEventListener( Event.ADDED_TO_STAGE, init ); } private function init( event:Event = null ):void { removeEventListener( Event.ADDED_TO_STAGE, init ); ncru = new NameCaseRu( ); /** * Форматированный вывод. */ /** * Можно не указывать пол и формат. */ trace( ncru.qFullName("Иванов", "Фёдор", "Ильич", NCL.INS) ); //Ивановым Фёдором Ильичом /** * В формате не обязательно использовать все слова. */ trace( ncru.qFullName("Иванов", "Фёдор", "Ильич", NCL.INS, NCL.MAN, "N F") ); //Фёдором Ильичом /** * Можно указать формат и не указывать пол человека. */ trace( ncru.qFullName("Иванов", "Фёдор", "Ильич", NCL.INS, 0, "S N") ); //Ивановым Фёдором /** * Можно указать все параметры. */ trace( ncru.qFullName("Иванов", "Фёдор", "Ильич", NCL.INS, NCL.MAN, "S N F") ); //Ивановым Фёдором Ильичом /** * В строке-формате могут присутствовать любые символы. */ trace( ncru.qFullName("Иванов", "Фёдор", "Ильич", NCL.INS, NCL.MAN, "Фамилия: S, Имя: N N, Отчество: F") ); //Фамилия: Ивановым, Имя: Фёдором, Отчество: Ильичом /** * Другие способы быстрого склонения. * */ /** * Пол можно не указывать. */ trace( ncru.qFatherName("Николаевич", NCL.DAT) ); /** * Если не указать падеж, получим массив со всеми падежами. */ trace( ncru.qFirstName("Андрей") ); /** * В ситувациях, когда не возможно определить пол, его полезно указать. */ trace( ncru.qLastName("Касюк", NCL.DAT, NCL.MAN) ); } } }
Метод qFirstName() ставит имя в нужный падеж по правилам пола. Методы qLastName и qFatherName занимаются аналогичными задачами относительно фамилии и отчества соответственно.
А теперь вернемся к практике.
К сожалению, т. к. предусмотреть всевозможные случаи склонения ФИО не в силах, то, скорей всего, будут ошибки в склонении ФИО. Такие ошибки могут иметь место в склонении сербских, армянских, грузинских фамилий, где точно определить пол сложнее нежели в русских и украинских фамилиях. Не смотря на это, существуют и такие случаи, когда определить пол не представляется возможным даже человеку. Например, такие имена и фамилии как Саша Коляденко и Женя Проскочило, а так же фамилии, заканчивающийся на согласные в сочетании с подобными именами. Пол данного ФИО, по умолчанию, определится как мужской.
Есть один важный момент. Среди сербских фамилий очень много фамилий, которые заканчиваются на -ич, например, Мила Йовович, Джон Малкович, Вася Бабич. Такие фамилии, как известно, в русском и украинском языках является отчеством. По этому подобные фамилии могут быть определены как отчество. Большинство таких фамилий занес в исключения. Тобиш, со 100% вероятностью такая фамилия будет определена правильно. Не смотря на сложности, фамилия будет просклонена правильно, т. к. правила склонения таких фамилий и отчеств одинаковы, но только для мужского пола. Согласно официальному правописанию, женские фамилии, например, Анна Шерер, не склоняются. То бишь, если не удалось определить пол по имени или отчеству, ФИО будет определено как мужское и склонено по правилам мужского пола. По этому прошу сообщать мне или Андрею в комментарии к посту о возникающих ошибках в склонении Вашего ФИО, а так же о ошибках в работе методов библиотеки.
Мои контакты: е-mail - vitalik.krivtsov@mail.ru, страница ВКонтакте - http://www.vk.com/vitalik.krivtsov, skype - v.krivtsov.
Контакты Андрея: е-mail - andriy@namecaselib.com, страница ВКонтакте - http://vk.com/seagullua, skype - bumer3-yuppie.
Просклонять ФИО можно по ссылке: http://namecaselib.com/ru/case/. Данное демо демонстрирует роботу библиотеки на PHP. Вскоре на сайте появится демо на ActionSctipt3.0.
Исходный код размещен на github.com. Распространяется под лицензией MIT или GPL Version 2. В папке lib лежит библиотека в формате swc. В папке src классы, использующие в качестве примеров к данному посту и код библиотеки.
Спасибо, что дочитали до конца!
Всего комментариев 10
Комментарии
![]() ![]() |
|
Цитата:
Р. Воробья Лева Ильича
Д. Воробью Леву Ильичу В. Воробья Лева Ильича Т. Воробьем Левым Ильичом П. на Воробье Леве Ильиче |
![]() ![]() |
|
КорДум, в самой свежей версии уже исправлено. На сайте была старая альфа версия, которой даже на github не было. А вот на AS3.0 у меня определяется как имя. Вскоре исправлю.
|
|
Обновил(-а) VitaliyKrivtsov 04.12.2011 в 19:05
|
![]() ![]() |
|
Цитата:
Воробьем Левым Ильичом
|
![]() ![]() |
|
Исправлено. Имя Витек/Витёк больше не определяется как фамилия. Склоняется по правилам мужского имени. Так же исправлены ошибки в склонении фамилии Воробей и похожих.
|
|
Обновил(-а) VitaliyKrivtsov 05.12.2011 в 20:33
|
![]() ![]() |
|
чуток
Цитата:
Материальна помощь проекту
|
![]() ![]() |
|
fish_r, спасибо =)
|
![]() ![]() |
|
2 Author: рекомендую настоятельно этот пост скопировать в wiki хотябы в том виде, котором тут есть. Круто поработал. Реально круто!
|
![]() ![]() |
|
Обновил(-а) VitaliyKrivtsov 08.12.2011 в 21:13
|
![]() ![]() |
|
Спасибо
|
Последние записи от VitaliyKrivtsov
- NameCaseLib. Склонение фамилии, имени и отчества (04.12.2011)
- Шаблон проекта для as3vkontaktelib под FlashDevelop (27.08.2011)
- Обновление as3vkontaktelib до версии .-90 (13.08.2011)
- VkontakteAPI. Разбор полётов. (18.05.2011)
- Библиотека для взаимодействия с Вконтакте API (11.03.2011)