Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > VitaliyKrivtsov

Рейтинг: 5.00. Голосов: 3.

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 - женский пол.
Для указания падежей русского и украинского языка написал общее константы для обеих языков. В версии для библиотеки на PHP используются разные. Мне показалось это излишним, т. к. различия не большая. В украинском языке падежей семь, вместо шести в русском. Для указания падежей русского и украинского языка используются константы:
  • NCL.NOM - именительный/називний.
  • NCL.GEN - родительный/родовий.
  • NCL.DAT - дательный/давальний.
  • NCL.ACC - винительный/знахідний.
  • NCL.INS - творительный/орудний.
  • NCL.ABL - предложный/місцевий.
Ниже приведены примеры использования метода q().
Код AS3:
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('Андрей Николаевич') );	
		}
 
	}
 
}
А так же пример с пользованием констант пола и падежа:
Код AS3:
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():
Код AS3:
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>
			 */ 
		}
 
	}
 
}
Работа с разными регистрами.
Не имеет значения, в каком регистре ФИО передается для склонения. Перед началом обработки каждого слова создается маска, где сохранено, какие буквы были в верхнем, а какие в нижнем регистре. После успешного склонения, регистр слов автоматически возвращается.
Ниже приведен пример:
Код AS3:
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) );//ПороСЁнКА ПёТРа 
		}
 
	}
 
}
Явное указание ФИО.
Библиотека отлично справляется со склонением русских и украинских ФИО. Иногда система склоняет ФИО не правильно. Чаще всего это связано с тем, что не возможно точно определить имя это, или фамилия, а так же не всегда можно правильно определить пол человека. Для того, что бы этого избежать в библиотеке есть возможность явно указать имя, фамилию, отчество, а так же пол. Этот метод с большей вероятностью правильно склонит ФИО.

Есть два способа для явного указания ФИО. В библиотеке есть метод:
Код AS3:
ncru.qFullName( lastName:String = "", firstName:String = "", fatherName:String = "", caseNum:int = 0, gender:int = 0, format:String = "S N F" )
Обязательно нужно указать хотя бы один параметр из перечисленных: lastName, firstName, fatherName. Необязательный параметр gender, который принимает значения NCL.MAN, NCL.WOMAN. Если пол не указать, система определит его самостоятельно. Параметр caseNum указывает номер падежа. Если его не указать, тогда метод вернет массив со всеми падежами. Параметр format отвечает за форматированный вывод ФИО. format — это строка, содержащая шаблон, по которому будет выведено ФИО. Шаблон имеет вид "S N F":
  • S – фамилия.
  • N – имя.
  • F – отчество.
Например:
  • "S N" - "Фамилия Имя"
  • "N F" - "Имя Отчество"
  • "S N F" - "Фамилия Имя Отчество"
В методе qFullName() можно указать любой удобный формат. Например:
Код AS3:
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) );
		}
	}
 
}
Помимо метода qFullName( ), есть еще три похожих метода: qFirstName(), qLastName(), qFatherName().
Метод 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

Комментарии

Старый 04.12.2011 18:24 КорДум вне форума
КорДум
 
Аватар для КорДум
Цитата:
Р. Воробья Лева Ильича
Д. Воробью Леву Ильичу
В. Воробья Лева Ильича
Т. Воробьем Левым Ильичом
П. на Воробье Леве Ильиче
Тут вопиющие косяки в имени.
Старый 04.12.2011 18:56 VitaliyKrivtsov вне форума
VitaliyKrivtsov
 
Аватар для VitaliyKrivtsov
КорДум, в самой свежей версии уже исправлено. На сайте была старая альфа версия, которой даже на github не было. А вот на AS3.0 у меня определяется как имя. Вскоре исправлю.
Обновил(-а) VitaliyKrivtsov 04.12.2011 в 19:05
Старый 04.12.2011 20:33 in4core вне форума
in4core
 
Аватар для in4core
Цитата:
Воробьем Левым Ильичом
Профит
Старый 04.12.2011 21:38 GBee вне форума
GBee
 
Аватар для GBee
Витька правильно склоняет, а ВКонтакт не может :о)
[IMG]http://dl.************/u/6132064/HB.png[/IMG]

И. Николаев Витек
Р. Николаева Витька
Д. Николаеву Витьку
В. Николаева Витька
Т. Николаевым Витьком
П. на Николаеве Витьке

а через Ё хуже
И. Николаев Витёк
Р. Николаева Витёка
Д. Николаеву Витёку
В. Николаева Витёка
Т. Николаевым Витёком
П. на Николаеве Витёке
Старый 05.12.2011 03:25 VitaliyKrivtsov вне форума
VitaliyKrivtsov
 
Аватар для VitaliyKrivtsov
Исправлено. Имя Витек/Витёк больше не определяется как фамилия. Склоняется по правилам мужского имени. Так же исправлены ошибки в склонении фамилии Воробей и похожих.
Обновил(-а) VitaliyKrivtsov 05.12.2011 в 20:33
Старый 05.12.2011 04:37 fish_r вне форума
fish_r
 
Аватар для fish_r
чуток
Цитата:
Материальна помощь проекту
Старый 05.12.2011 20:31 VitaliyKrivtsov вне форума
VitaliyKrivtsov
 
Аватар для VitaliyKrivtsov
fish_r, спасибо =)
Старый 05.12.2011 23:36 ~~~ вне форума
~~~
 
Аватар для ~~~
2 Author: рекомендую настоятельно этот пост скопировать в wiki хотябы в том виде, котором тут есть. Круто поработал. Реально круто!
Старый 07.12.2011 16:41 VitaliyKrivtsov вне форума
VitaliyKrivtsov
 
Аватар для VitaliyKrivtsov
~~~, ок, будет пост и на wiki.

Завели аккаунт на twitter. Присоединяйтесь! Будем постить обновления к данной библиотеки, а так же на PHP и C#.
Обновил(-а) VitaliyKrivtsov 08.12.2011 в 21:13
Старый 02.02.2012 12:55 Inet_PC вне форума
Inet_PC
 
Аватар для Inet_PC
Спасибо
 

 


Часовой пояс GMT +4, время: 23:23.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.