Как я упоминал вчера, есть идея немного поразбираться с тезаурусом Word в Delphi. Знания эти могут быть применены и для работы в Инернет в том числе. Для начала стоит сразу определиться с чем, собственно, мы будем иметь дело. Что такое тезаурус? Вот, что нам говорит Wikipedia:
Тезаурус в современной лингвистике — особая разновидность словарей общей или специальной лексики, в которых указаны семантические отношения (синонимы, антонимы, паронимы и т. п.) между лексическими единицами. Таким образом, тезаурусы, особенно в электронном формате, являются одним из действенных инструментов для описания отдельных предметных областей.
В отличие от толкового словаря, тезаурус позволяет выявить смысл не только с помощью определения, но и посредством соотнесения слова с другими понятиями и их группами, благодаря чему может использоваться в системах искусственного интеллекта.
Ну, до искусственного интеллекта мне как до Китая раком,а в целях синонимизации некоторых частей текста тезурус применить можно. Итак, тезаурус содержит не только синонимы слова, но и атонимы, а также может показать нам другие значения слова. Проверим сказанное на примере. Запускаем Word, пишем одно слово: «Большой» и смотрим, что нам скажет тезаурус об этом слове:
Картинка кликабельна. То, что выделено жирным — это значения слова «большой», т.е. большой в смысле высоты — «высокий», в смысле размера — «большущий» и т.д. Всего тезаурус содержит семь различных значений этого слова, что более, чем достаточно для реализации простенького примера в Delphi.
Сегодня посмотрим как можно:
- Вывести все значения слова
- Узнать все синонимы для конкретного значения слова
- Узнать все антонимы слова
Думаю, что для одного раза будет вполне достаточно.
Тезаурус Word в Delphi. Как узнать все значения (смыслы) слова?
Создадим простенькое приложение Delphi, как показано на рисунке:
В ListBox’ы будем выводить список антонимов и синонимы для значения слова. Значение будет выбираться из ComboBox.
Теперь, что касается конкретно тезауруса, как он определен в объектной модели Word. В объектной модели Word 2003 (да и в других версиях тоже) тезурус определен, как объект SynonymInfo. Чтобы безпрепятственно добраться до тезауруса Word из Delphi и получить необходимую нам информацию, достаточно воспроизвести теже действия, которые Вы совершаете в окне MS Word, т.е.:
- Создаем документ
- Записываем слово
- Выделяем слово
- Жмем «Тезаурус»
Есть и другой способ, но сегодня ограничимся такой «имитацией» действий пользователя. Определим следующие глобальные переменные:
var Word: OleVariant;//объект Word.Application SynInfo: OleVariant; //объект SynonymInfo Selected: OleVariant; //выделеный фрагмент текста SynLst,AntLst: OleVariant;//списки синонимов и антонимов
Теперь в обработчике onClick кнопки напишем следующее:
[...] if not VarIsEmpty(Word) then begin Word.Quit; Word:=Unassigned; end; Word:=CreateOleObject('Word.Application'); Word.Documents.Add; Word.DisplayAlerts:=false; Word.Documents.Item(1).Activate; Word.ActiveDocument.Range.InsertBefore(Edit1.Text); Word.ActiveDocument.Range.Select; Selected:=Word.Selection; [...]
Так как нам не требуется постоянно держать в памяти объект Word, то каждый раз при нажатии кнопки мы будем выгружать старый объект и создавать новый. В приведенном листинге мы совершили следующие действия: создали документ, записали в новый документ слово или словосочетание из Edit’а, выделили всё, что записали создали объект Selection (переменная Selected), который и будем теперь использовать для работы с тезаурусом.
Получаем объект тезауруса:
SynInfo:=Selected.Range.SynonymInfo;
У объекта определены следующие свойства:
Found : boolean — True, если для слова или словосочетания в тезаурусе определены синонимы, антонимы, родственные слова и т.д.
Пример использования:
if Selected.Range.SynonymInfo.Found then ShowMessage('Тезаурус содержит сведения о слове/выражении') else ShowMessage('В тезаурусе нет сведений');
MeaningCount : integer — возвращает количество записей в списке значений слова.
MeaningList: array of variant — одномерный массив, содержащий все значения слова.
Чтобы получить список всех значений слова, мы можем сделать так:
Создаем ещё одну переменную в которой будем хранить список значений и две переменные для счётчика и получения количества значений в списке:
var MeanLst: OleVariant; i,meaningCount:integer;
Теперь дописываем обработчик onClick:
[...] meaningCount:=SynInfo.MeaningCount; MeanLst:=SynInfo.MeaningList; ComboBox1.Items.Clear; for i:=1 to meaningCount do ComboBox1.Items.Add(MeanLst[i]); [...]
Можно обойтись и без лишних переменных, но для примера, думаю, они нам пригодятся.
Теперь запускаем приложение, записываем в Edit слово «большой» и убеждаемся, что в ComboBox содержаться семь различных значений слова:
Тезаурус Word в Delphi. Как узнать все антонимы слова?
Следующее свойство объекта SynonymInfo — это
AntonymList : array of variant — одномерный массив антонимов слова.
Можно было бы по аналогии со списком значений предположить, что есть свойство содержащее количество антонимов. А нет такого свойства :) Придётся самим в Delphi узнавать размер массива. Например, можно дописать наш обработчик onClick так:
var AntLst: OleVariant; [...] ListBox2.Items.Clear; AntLst:=SynInfo.AntonymList; for i:=1 to VarArrayHighBound(AntLst,1) do ListBox2.Items.Add(AntLst[i]); [...]
VarArrayHighBound — возвращает верхний предел измерения вариантного массива.
Запускаем приложение и получаем список антонимов:
Теперь мы вплотную подошли к работе со списком синонимов для слова.
Тезаурус Word в Delphi. Как определить все синонимы для значения слова?
Как определяется этот список в объекте? У слова может быть несколько значений — в этом мы уже убедились. Соответственно, каждое значение слова может иметь разные синонимы. Поэтому список синонимов представляет собой некий многомерный массив строк, где первое измерение соответствует количеству значений слова, а второе — список синонимов для этого значения. Чтобы получить список синонимов для конкретного значения слова необходимо указать это значение при обращении к списку следующим образом (пишем обработчик onChange у ComboBox):
procedure TForm5.ComboBox1Change(Sender: TObject); var i:integer; begin ListBox1.Items.Clear; SynLst:=SynInfo.SynonymList[Meaning:=ComboBox1.ItemIndex+1]; for i:=1 to VarArrayHighBound(SynLst,1) do ListBox1.Items.Add(SynLst[i]); end;
Теперь, мы можем проверить нашу программу в действии — достигнуты все поставленные цели: счиываются значения слова, считываются антонимы, получаются синонимы для конкретного значения слова. И всё это реализовано в Delphi.
Но это ещё не все полечные свойства объекта SynonymInfo, которые мы модем использовать при работе с Word в Delphi. Также можно использовать следующие свойства объекта:
RelatedExpressionList : array of variant — возвращает список выражений связанных со словом или выражением. Как правило, в тезаурусе существует очень мало связанных выражений. По крайней мере для приведенного в посте примера («большой») список оказался пустым.
RelatedWordList : array of variant — тоже самое, что и предыдущий список, но только содержит не фразы, а слова. Также как и RelatedExpressionList, в большинстве случаев этот список оказывается пустым.
PartOfSpeechList: array of integer — список содержащий части речи, соответствующие значению, найденого слова или фразы. В списке могут содержаться следующие значения (константы):
wdAdjective = 0 — прилагательное
wdAdverb = 2 — наречие
wdConjunction = 5 — соединение (союз)
wdIdiom = 8 — идиома
wdInterjection = 7 — междометие
wdNoun = 1 — существительное
wdOther = 9 — другие части речи
wdPreposition = 6 — предлог
wdPronoun = 4 — местоимение
wdVerb = 3 — глагол.
Этот список удобно использовать, например, для определения части речи, используемой в тезаурусе.
Вот такой получился краткий экскурс в работу с тезаурусом Word в Delphi. Надеюсь эта информация окажется Вам, как и мне, полезной при разработки программ для Сети.
Попробовал работу с тезаурусом от Word 2010 по предлагаемой методике. Все ок, но на некоторых словах (например: «сообщаем», «просим») выдает ошибку нехватки памяти. Ошибка возникает при получении объекта тезауруса: SynInfo:=Selected.Range.SynonymInfo;