Словарь DIC алгоритм работы со звездочкой (*)

Говорящий текстовый редактор с открытым кодом, предназначенный для чтения вслух и записи в аудиофайл текстовых файлов с использованием пакетов речевых функций SAPI4\SAPI5.

Модератор: flegont

Ответить
Аватара пользователя
tonio_k
V.I.P.

Словарь DIC алгоритм работы со звездочкой (*)

#1

Сообщение tonio_k »

Рассмотрим Простую схему предложения:
Прилагательное глагол существительное.
Если взять в контексте существительное и недалеко стоящее в предложении Прилагательное или глагол не разделенные знаками препинания, то с вероятностью 90% это Прилагательное или глагол относятся по смыслу к существительному. Это так же применимо во всех их комбинациях между собой.
Правила в словарях и ищут эти контексты так как смысловая нагрузка программе не доступна.
Более сложные сочетания со знаками препинания - это уже более сложные в выявлении закономерностей особенности русского языка.
Идём от простого к сложному:
применение звездочки как части слова вполне логична - так как облегчает замены связанные с закономерностями связок прилагаттельное с существительным
*ого рога=ого рогА
С учетом закономерностей русского языка можно предположить, что: "*ого (с оговоркой или уточнением) рога" тоже на выходе будет звучать как рогА Пример:
разбитого топором рогА
Причем вместо "топором" может быть "мечом", "силой мысли" и т.д. - т.е. непредсказуемое слово или два, а может и три!

Давайте вместо "силой мысли" применим ту же звездочку:
*тые * * рога=тые рогА

Но тут звездочка в Демагоге "перескакивает" простой по логике схему: звездочка = только слово, и сразу включает в себя дополнительные комбинации, которые к 90% вероятности правильности составления правила дает минус 10-20% на ложные срабатывания. Пример:
Проклятые рога. Два рога торчали из за камня.

Если *тые * * рога=тые рогА поставить как первое правило для срабатывания. а уточняющие правила при алгоритме перебора в конец:
Два рога=Два рОга
рога торчали=рогА торчали

то эти правила "подчистят" ложные срабатывания.

Но с другой стороны, если звездочку сделать ТОЛЬКО слово без знаков препинания, то придумать ошибочное срабатывание в контексте предложения *тые * * рога=тые рогА не так просто и мало вероятно встретить в реальном тексте.

Так что мое мнение, что звездочка очень эффективна как часть слова, но применяя ее в качестве отдельного слово а иногда и в качестве окончания слова - уже применять не сильно хочется.

А вот если * сделать как аналог (\w+) в rex словарях - то её применение станет на много удобнее и эффективнее.

На вопрос а что делать если нужен знак препинания? Его что, каждый раз прописывать?
Отвечу - да!
Если посмотреть словари которые применяются на практике, то правила, где "нужно" прописать какой либо знак препинания - обычно словосочетание, которое без этого знака наоборот делает правило ошибочным. Причем не какой угодно знак, а конкретный - например только точка или только запятая. Более того - есть правила, где нужно прописать ВСЕ знаки препинания КРОМЕ схемы: слово пробел слово. А звездочка и тут не применима, так как включает в себя не только знак препинания но и его отсутствие.

Вот мои рассуждения про сегодняшний алгоритм работы звездочки для Демагога.


Отправлено спустя 29 минут 1 секунду:
Пример рога торчали=рогА торчали - некорректный. Извините :boy_blushed:

Аватара пользователя
balaamster
Обыватель

Словарь DIC алгоритм работы со звездочкой (*)

#2

Сообщение balaamster »

tonio_k писал(а):
13 ноя 2018 17:11
*ого рога=ого рогА
Правила со звёздочками, как и регексы с поиском по окончанию, коварны
"Обладатель большого рОга"
Я попался на правиле:
*ие руки=ие рУки

Но: движение рукИ, две тонкие рукИ
Хотя, вероятность таких сочетаний ниже, чем сильные рУки, маленькие рУки
Возможно, таким можно и принебречь

Аватара пользователя
tonio_k
V.I.P.

Словарь DIC алгоритм работы со звездочкой (*)

#3

Сообщение tonio_k »

balaamster писал(а):
13 ноя 2018 17:33
регексы с поиском по окончанию, коварны
именно по этой причине у меня все правила со звёздочками вынесены в отдельный словарь и применяются к тексту первыми по очереди перед всеми остальными обычными словарями DIC. Так сказать от, обобщенных правил статистически средне вероятным (со звездочкой), к более конкретным и однозначным от двух слов в правиле к тресм словам и более. Тему звёзд поднял так как текущий алгоритм статистически уж "слишком" обобщен.

Аватара пользователя
flegont
V.I.P.

Словарь DIC алгоритм работы со звездочкой (*)

#4

Сообщение flegont »

Принцип работы со звездочкой в dic-словарях меняться не будет. Звездочка - это любые символы. Это - общепринято и всем привычно.

Что же касается возможности для пользователей творить собственные алгоритмы словарных замен, на уровне скриптов, исключительно средствами Lua, не обращаясь к таким заимствованиям из Демагога, как функция WFilter() - будущее покажет.

Аватара пользователя
tonio_k
V.I.P.

Словарь DIC алгоритм работы со звездочкой (*)

#5

Сообщение tonio_k »

:cheerleaderkid: ура! эврика!

Нашел схему, которая работает!
Проблемы, обсуждаемые в этой ветке с ограничением звездочки на предмет знаков препинания и перескакивания на следующее предложение типа:из * воды=из воды для словарей DIC больше не существует!

Схема:
Данная схема работает только в программе Демагог!
Нужно все правила со звездами, окруженные пробелами, перенести в отдельный словарь.Для их выявления Можно воспользоваться поиском по шаблону rex ^(.)*\s\*\s(.)*=(.)*(.)*$

Всего нужно 3 словаря:
1) словарь подготовки (REX )
2) словарь со звездочками (DIC)
3) словарь - чистка (DIC)
Словари должны сработать строго друг за другом между собой:

1) первый словарь - REX всего одна строка:

Код: Выделить всё

([а-яё])\b=$1_
2) второй словарь - каждое слово, в том числе и звездочка, в правиле (в его левой части) на конце должно иметь концовку "_", (обратите внимание как отделяются знаки препинания). Символ Концовка может быть любой - главное что бы он была уникальным (не встречался в тексте) и удобным при наборе и редактирования правил в словаре.
► Показать

Что бы "любое слово" соответствующее звездочке подставилось корректно, надо в правой части правила в том месте где оно должно подставиться - вставляем знак концовки "_" - окруженный пробелами.

3) словарь чистки - запускать ОБЯЗАТЕЛЬНО - в режиме прямого перебора.
► Показать
Пример для тестирования (правила для словаря см. выше):
► Показать
после обработки тремя словарями на выходе получаем:
► Показать

Аватара пользователя
flegont
V.I.P.

Словарь DIC алгоритм работы со звездочкой (*)

#6

Сообщение flegont »

Любопытная методика! Принцип разделения буквенных и небуквенных символов.
Интересно, а как по затратам времени на больших словарях? И/или больших текстах - размером с книжку.

Аватара пользователя
tonio_k
V.I.P.

Словарь DIC алгоритм работы со звездочкой (*)

#7

Сообщение tonio_k »

Скажу сразу, Этот словарь должен работать в режиме быстрого алгоритма. Так как в результате исправлений, текст становится уникальным и повторно к одному и тому же участку текста правила, которые находятся ниже не сработают. Если режим прямого перебора включен в настройках по умолчанию. То рекомендуется Этот словарь отсортировать по стандарту для словарей DIC. Хотя можно заморочиться и правую часть правила сразу записывать с концовкой На каждом слове. Тогда последовательный перебор будет применим.

Думаю это словарь будет работать по времени так же как обычный словарь dic со звёздочками. Зависит от алгоритма.


Отправлено спустя 6 минут 18 секунд:
Главное приемущество это быстрота и удобство в работе со словарем. Не требует особых знаний, как в rex словарях. Скопировал, вставил, добавил концовку добавил *_ и правило готово.


Отправлено спустя 15 минут 10 секунд:
Самое то главное не отметил!
( *_ ) - это значит что слово будет найдено без запятых! Т.е. полный аналог (\w+) в регулярных выражениях rex

Аватара пользователя
flegont
V.I.P.

Словарь DIC алгоритм работы со звездочкой (*)

#8

Сообщение flegont »

Да, действительно, полный аналог \w+ Без любых препинаний, только буквенно-цифровые символы. Отличный результат.

Аватара пользователя
tonio_k
V.I.P.

Словарь DIC алгоритм работы со звездочкой (*)

#9

Сообщение tonio_k »

tonio_k писал(а):
29 ноя 2018 20:23
Т.е. полный аналог (\w+) в регулярных выражениях rex
к сожалению, как оказалось, не полный.

Выше обозначенный алгоритм имеет один недостаток:
правила, имеющие, например, вид:
выгнул* брови_=выгнул брОви - все равно может сработать и на тексте:
выгнул? Брови
т.е. НЕ в пределах одного предложения.
А в таком виде:
выгнул*_ брови_=выгнул_ брОви_ правило вообще не работает.

Добавил маленькие изменения в алгоритм:
tonio_k писал(а):
29 ноя 2018 19:26
1) первый словарь - REX
► Показать
tonio_k писал(а):
29 ноя 2018 19:26
3) словарь чистки - запускать ОБЯЗАТЕЛЬНО - в режиме прямого перебора.
► Показать
Теперь любое правило:
ещё_ *_ минут* и_ дома_ закончились_=ещё _ минут и домА закончились
выгнул* брови_=выгнул брОви

и даже:
*нул* брови_=нул брОви
сработают на соответствующем им тексте, при условии что нет знаков препинания .,:;!?

Вот теперь полный аналог (\w+) :ok:


Отправлено спустя 4 часа 38 минут 38 секунд:
Небольшое дополнение.

правило ([а-яё]_\.)=$1 z.k может некорректно заменить троеточие "..."

поэтому в 1) словаре надо перед этим правилом добавить:

Код: Выделить всё

\.\.\.=…
([а-яё]_\…)=$1 z…k
а в 3) словаре аналогично добавить строку:

Код: Выделить всё

*… z…k=...
Еще момент. Если очень нужно, то 1) словарь (rex) можно заменить словарем DIC - применять ОБЯЗАТЕЛЬНО - в режиме прямого перебора.
► Показать

Аватара пользователя
flegont
V.I.P.

Словарь DIC алгоритм работы со звездочкой (*)

#10

Сообщение flegont »

Неоднозначность dic-правил с отдельно стоящими звездочками
Если в шаблоне поиска есть отдельно стоящие звездочки, то программа предполагает, что каждому слову шаблона соответствует слово замены из правой части правила.

все * *ло=всё ло

Если однозначное соответствие левой и правой частей отсутствует, то результат применения "звездного правила" будет далек от ожидаемого.

не о чем * * * *вать=нЕочем вать

Не о чем нам с вами разговаривать! ==> нЕочем вать нам с вами разговари! :evil:

Решение:
не о чем * * * *вать=нЕочем ~ ~ вать
~=


Не о чем нам с вами разговаривать! ==> нЕочем нам с вами разговаривать! :ok:

Аватара пользователя
tonio_k
V.I.P.

Словарь DIC алгоритм работы со звездочкой (*)

#11

Сообщение tonio_k »

после некоторого времени эксплуатации вышеописанного механизма применения правил со звездочками в словарях DIC пока остановился на такой схеме:

1) Необходимые настройки Демагог:
Сервис-Общие настройки-Чтение. Галочки в указанных пунктах должны быть убраны
► Показать
Если словарь запускается через скрипт, то перед WFilter применить:
FastDic(false, false) -- прямой перебор без сортировки правил.

2)Требования к словарю: словарь DIC разбит на 3 части:
#1) Вставка ограничителя слова - не редактируется
#2) Словари замен. Ограничитель слова _ (нижнее подчеркивание) на конце каждого слова
#3) Удаление ограничителя слова - не редактируется
Пример готового словаря, состоящего всего из 1 правила:
► Показать
*все 3 части (без сортировки) можно добавить к любому уже существующему словарю, при условии, что к нему применяются условия из п1

3) Требования к созданию правил (вторая часть словаря)

--- в левой части правила:
- все слова закачиваются на "_" (нижнее подчеркивание) Пример: слово_;
- отдельная звёздочка, означающая любое целое слово, должна закачиваются на "_" (нижнее подчеркивание) Пример: *_;
- звёздочка на конце слова НЕ должна заканчиваться "_" (нижним подчеркиванием)Пример: слово*;
- любой знак препинания должен отделяется от слова пробелом и заканчивться на / (слэш)

---в правой части правила:
- "_" (нижнее подчеркивание) на конце слов НЕ обязательно - можно пропустить;
- знак препинания можно "склеить" с идущим перед ним словом

Примеры вариантов записи одного и того же правила:

Код: Выделить всё

*благодар* лорда_ *_ за_ все_ ,/ что_ он_ для_=благодар лорда _ за_ всё_ ,/ что_ он_ для_
*благодар* лорда_ *_ за_ все_ ,/ что_ он_ для_=благодар лорда _ за всё, что он для
Пример текста для тестирования:
Возблагодарим лорда Бекингема за все, что он для нас сделал!

Вместо "_" (нижнее подчеркивание) и / (слэш) вы можете использовать свой любой не буквенно/цифровой символ, сделав соответствующие замены в словаре.

*Напоминаю, эта схема имеет смысл только для правил со звездочками:
-в которых звёздочка находится на конце слова и после этого слова идет следующее слово;
или
-звёздочка означает отдельно идущее целое слово.

Идея вышеописанной схемы - что бы звездочка в словаре DIC всегда трактовалась ТОЛЬКО как "любое слово/часть слова без прилегающих к нему знаков препинания".

Аватара пользователя
tonio_k
V.I.P.

Словарь DIC алгоритм работы со звездочкой (*)

#12

Сообщение tonio_k »

UPD Вот такой вариант правила:

Код: Выделить всё

*благодар* лорда_ *_ за_ все_ */=благодар лорда _ за всё /
Требует обязательное наличие знака препинания [.,?!], без которого правило не сработает

Аватара пользователя
tonio_k
V.I.P.

Словарь DIC алгоритм работы со звездочкой (*)

#13

Сообщение tonio_k »

tonio_k писал(а):
13 фев 2020 14:37
что бы звездочка в словаре DIC всегда трактовалась ТОЛЬКО как "любое слово/часть слова без прилегающих к нему знаков препинания".
Реализовал эту задачу через функцию для скрипта lua. При этом, правила со звёздочками в dic словарях можно записывать по старинке в стандартном для словарей dic синтаксисе:

Код: Выделить всё

*благодар* лорда * за все, что он для=благодар лорда за всё, что он для

Функция сама вставит в изменяемый текст метки границ слова, преобразует правила в словаре так, что бы они срабатывали с учетом меток границ слова, применит словарь замен, удалит из текста ранее вставленные метки.

Код: Выделить всё

function STARSWFilter(j1, j2, path_dic) 
local dic_star=LoadText(path_dic) -- загружаем текст из словаря
--Добавляем к правилам поддержку границы слова:
dic_star = string.gsub(dic_star,'[\r\n]+','\r')
dic_star = string.split(dic_star,'\r')--в таблицу
for i=1,#dic_star do
dic_star[i]=DicToLua(dic_star[i])
end
dic_star = table.concat(dic_star, '\r')--в текст
dic_star = string.gsub(dic_star,'%%%d+','#')
local r=[[
*%f[%w]*::
*(%w-)*::*
*(%w+)*::*
*%.*::.
*%?*::?
*%-*::-
*%%*::%
]]
local o = {}
o.Reading_HashAlgorithm = false
Settings(o)
dic_star=DicRepl(dic_star,{r})
--Вставляем в правила метки границы слова: -- символы для REX: "]"=\x5D; ")"=\x29
r=[[
#Вставка меток границ слова в текст 
([а-яё])\b=$1_
#резервируем три точки
_\.\.\.=_…
#отделяем знаки препинания от правой границы слова (нижнее подчеркивание "_" включен в поиск, что бы замена срабатывала ТОЛЬКО в связке с правой границей слова)
_([.,!:;\x29\x5D?»"])=_ $1/
#возвращаем три точки
_…=_ ./ ./ ./
]]
dic_star=RexRepl(dic_star,{r},false)--полоса прогресса отключена
dic_star=string.gsub(dic_star,'_%*','*')
dic_star=string.gsub(dic_star,' %* ',' *_ ')
dic_star=string.gsub(dic_star,' %* ',' *_ ')
dic_star=string.gsub(dic_star,' # ',' _ ')
dic_star=string.gsub(dic_star,' # ',' _ ')
dic_star=string.gsub(dic_star,' # ',' _ ')
dic_star=string.gsub(dic_star,'_#','')
dic_star=string.gsub(dic_star,'#','')
dic_star=RexRepl(dic_star,{[[
^@=$$
[\r\n]+=\r
]]})

SaveToFile({dic_star},HomeFolder('')..'#звезд+@.dic')--для отладки сохранить

s=WText(j1)
--Вставляем в сам текст метки границы слова: -- символы для REX: "]"=\x5D; ")"=\x29
r=[[
#Вставка меток границ слова в текст 
([а-яё])\b=$1_
#резервируем три точки
_\.\.\.=_…
#отделяем знаки препинания от правой границы слова (нижнее подчеркивание "_" включен в поиск, что бы замена срабатывала ТОЛЬКО в связке с правой границей слова)
_([.,!:;\x29\x5D?»"])=_ $1/
#возвращаем три точки
_…=_ ./ ./ ./
]]
s=RexRepl(s,{r},false)

--применяем правила с границами слова:
local o = {}
o.Reading_HashAlgorithm = false
o.Reading_OrderedRules = false
Settings(o)
s = DicRepl(s,{dic_star})


--убираем метки границ  слов
r=[[#Удаление меток границ слова
_=
[ ]+([.,!:;\x29\x5D?»"])/=$1
]]			
s=RexRepl(s,{r},false)
s=GoodText(s)
WNew(j2,s,false)  
return s
end
Пример применения:

Код: Выделить всё

--к содержимому окна 1 применить словарь "40.1_звезды аналог (w+@).dic", результат замен поместить в окно 0
STARSWFilter(1, 0, HomeFolder('dic')..'40.1_звезды аналог (w+@).dic')
WActive(0)
tonio_k писал(а):
13 фев 2020 14:37
UPD Вот такой вариант правила:

*благодар* лорда_ *_ за_ все_ */=благодар лорда _ за всё /
Требует обязательное наличие знака препинания [.,?!], без которого правило не сработает
тоже будет работать. Правило нужно записать в таком виде:

Код: Выделить всё

*благодар* лорда * за все */=благодар лорда  за всё /

Ответить

Вернуться в «Demagog»