SFC wrote:> P.S. По хорошему ещё, наверное, выпиливать аббревиатуры и сокращения (dr. и прочее).
Не думаю. Пусть будет общее правило: удалять знаки препинания и сравнивать. Абревиатуры будут в словаре - и оно будет работать так как сейчас есть.
"Dr. Watson" превратиться в "Dr" и "Watson", как-то это не так, хотя да, по идее можно убрать, добавив "dr" в словарь.
SFC wrote:По идее или fr554 должно остаться или fr. Тут я сам не соображу.
Если текст будет не художественный, то, например, "RFS207-9, RFS2079" превратиться в "rfs", что вряд ли будет понятно сразу, тогда лучше не убирать цифры.
SFC wrote:Замечание:
От hgfh остается hgf
т.е. съедается последний символ. И так у любого последнего слова.
SFC wrote:Я добавил третью строку:
nod's far
nod's - исчезает, а должен остаться. И от hgfh остается hgf все равно
Вроде исправил, это от первых вариантов осталось, "don't" превращалось в "don" и "t", что неправильно.
SFC wrote:Вот так вроде нормально делает первый шаг - приводит в столбец:
См. строку 46
Есть проблема: как оставить слова с цифрами, подождём, может быть, у кого-нибудь ещё будут идеи.
Posted: Mon Nov 16, 2015 4:26 pm
by Kley
SFC wrote:Когда читаешь англ текст встречаются незнакомые слова. Хотелось бы не читая текста сразу определить какие слова незнакомые чтобы заранее их выучить и уже спокойно читать текст.
Ключевое "слова". Зачем выучивать fr554? Это не слово, не англ. слово, не русское...
Может стоит создать еще один файл (файл исключений), куда юзер будет вносить слова, типа "the, fr, do, not" - "знакомые" со школьной скамьи. Эти слова удалять до всей обработки.
p.s.
Skif_off
Все работает. Давайте пока на этом остановимся.
Подумаем. По горячим следам - все работает идеально вроде. Позже накоплю статистику - выскажу критику если она будет конечно.
Слова с цифрами убирает - так и должно быть. Kley прав.
Слова из одной буквы убирает - это также есть ОК.
Создавать еще один файл = исключений нет смысла. Это и есть единственный файл dictionary со всеми словами которые надо убирать и т.д.
Большое спасибо
Добавлено:
Великолепно. Сейчас поместил в словарь Longman 9000. и проверил новость от BBC. Результат ожидаем.
if (aWordList[i].length > 1)
pText += aWordList[i] + "\r";
substr() возвращает не всю строку.
Posted: Mon Nov 16, 2015 4:49 pm
by Kley
Skif_off
"Заказчик" доволен, ну и слава Богу.
SFC wrote:чтобы сделать неск копий скрипта на случаи разных языков
Хотя вряд ли он пробовал с "разными языками". Ведь скрипт напрочь удаляет все "нелатинские" символы.
Добавлено. Skif_off,
извините меня приставучего и торопыгу. Возможно я просто не разобрался, но нужна ли функция Dubl?
GetWords уже просто не добавляет дубли. И pText.sort() тоже она делает.
Posted: Mon Nov 16, 2015 6:47 pm
by Skif_off
Kley
Согласен, в таком виде ни к чему, исправил.
SFC wrote:сделать неск копий скрипта на случаи разных языков.
Как вариант - составить список символов, типа французский (исходя из предположения, что toLowerCase() корректно сработает со всеми буквами):
var aWord;
var oDict;
var oDupl;
var i;
if (aWord = AkelPad.GetTextRange(0, -1).toLowerCase().match(/[^\s`"\\\|\[\]\(\)\{\}<>,\.;:\+\-=~!#\$%\^&\*\/\?«»\d]+/g))
{
oDict = GetDictionary();
oDupl = {};
for (i = aWord.length - 1; i >= 0; --i)
{
if ((aWord[i] in oDict) || (aWord[i] in oDupl))
aWord.splice(i, 1);
else
oDupl[aWord[i]] = true;
}
AkelPad.SetSel(0, -1);
AkelPad.ReplaceSel(aWord.join("\r\n"), -1);
}
function GetDictionary()
{
var aDict = AkelPad.ReadFile(AkelPad.GetAkelDir(1) + "\\Tools\\dictionary.txt", 0x10 /*OD_ADT_NOMESSAGES*/, 65001 /*UTF-8*/, 0).split(/[\r\n]+/);
var oDict = {};
var i;
for (i = 0; i < aDict.length; ++i)
oDict[aDict[i]] = true;
return oDict;
}
Posted: Tue Nov 17, 2015 4:27 pm
by Skif_off
KDJ wrote:without sorting (it should work faster)
But with sorting is more comfortable
Words with numbers are not needed and required certain language only (not all words).
My JScript knowledges is bad and now I don't know how better to do
Is replace() more fast than splice()? And if the array is very large?
Posted: Tue Nov 17, 2015 5:08 pm
by Kley
Skif_off
Первое сообщение SFC, по этой теме, скопировал несколько сот раз в файл. Получилось ~110 000 строк (файл ~13M).
Ваш скрипт работал буквально пару секунд. Куда уж быстрей
Posted: Wed Nov 18, 2015 9:48 pm
by Skif_off
Kley
Вопрос про скорость в значительной мере теоретический, а не про конкретный скрипт: гуглил, но так и не понял, что происходит с массивом при использовании splice(). По идее удаление ячейки в произвольном месте сдвинет ячейки ниже и заставит пересчитать индексы? Тогда с большим массивом понадобится больше ресурсов и выше шанс ошибки, чем при работе со строкой. Гипотетически.
// Отсюда http://akelpad.sourceforge.net/forum/viewtopic.php?p=29871#p29871 и ниже,
// скрипт http://akelpad.sourceforge.net/forum/viewtopic.php?p=29873#p29873
// 2015-11-16
var nTime = new Date().getTime();
var pText = AkelPad.GetTextRange(0, -1).toLowerCase();
var aWordList = GetWords(pText);
var aDict;
pText = "";
for (i = 0; i < aWordList.length; ++i)
{
if (aWordList[i].length > 1)
pText += aWordList[i] + "\r";
}
// Читаем \AkelFiles\Tools\dictionary.txt (в UTF-8 без BOM) и режем в массив
aDict = AkelPad.ReadFile(AkelPad.GetAkelDir(1) + "\\Tools\\dictionary.txt", 0x10 /*OD_ADT_NOMESSAGES*/, 65001 /*UTF-8*/, false).split(/[\r\n]+/);
// Ищем в тексте документа слова из массива, если есть - удаляем
for (var i = 0; i < aDict.length; i++)
{
if (pText.indexOf(aDict[i]) >= 0)
{
oPattern = new RegExp("^" + aDict[i] + "\r+", "gm");
pText = pText.replace(oPattern, "");
}
}
// Вставляем отсутствующие слова в документ, заменяя существующий текст
AkelPad.SetSel(0, -1);
AkelPad.ReplaceSel(pText);
WScript.Echo("Time: " + (new Date().getTime() - nTime) + " ms");
// Kley, http://akelpad.sourceforge.net/forum/viewtopic.php?p=29879#p29879
function GetWords(pText)
{
var aAllWords;
var nAllWords;
var aWords = [];
var sWord;
var i = 0;
aAllWords = pText.match(/[^\s`"\\\|\[\]\(\)\{\}<>,\.;:\+\-=~!#\$%^&\*/\?«»]+/g);
nAllWords = aAllWords ? aAllWords.length : 0;
if (nAllWords)
{
aAllWords.sort();
while (i < nAllWords)
{
sWord = aAllWords[i];
++i;
while ((i < nAllWords) && (sWord == aAllWords[i]))
{
++i;
}
// Пропускаем итерацию, если в строке содержится что-нибудь кроме "a-z'"
if (sWord.search(/[^a-z']+/g) >= 0) continue;
aWords.push(sWord);
}
}
return aWords;
}
var nTime = new Date().getTime();
var aWord;
var oDict;
var i;
//if (aWord = AkelPad.GetTextRange(0, -1).toLowerCase().match(/[^\s`"\\\|\[\]\(\)\{\}<>,\.;:\+\-=~!#\$%\^&\*\/\?«»\d]+/g))
if (aWord = AkelPad.GetTextRange(0, -1).toLowerCase().match(/[^\s`"\\\|\[\]\(\)\{\}<>,\.;:\+\-=~!#\$%\^&\*\/\?«»]+/g))
{
oDict = GetDictionary();
for (i = aWord.length - 1; i >= 0; --i)
{
// if (aWord[i] in oDict)
if ((aWord[i] in oDict) || (aWord[i].length == 1) || (/[^a-z']+/.test(aWord[i])))
aWord.splice(i, 1);
else
oDict[aWord[i]] = true;
}
AkelPad.SetSel(0, -1);
AkelPad.ReplaceSel(aWord.join("\r"), -1);
}
WScript.Echo("Time: " + (new Date().getTime() - nTime) + " ms");
function GetDictionary()
{
var aDict = AkelPad.ReadFile(AkelPad.GetAkelDir(1) + "\\Tools\\dictionary.txt", 0x10 /*OD_ADT_NOMESSAGES*/, 65001 /*UTF-8*/, 0).split(/[\r\n]+/);
var oDict = {};
var i;
for (i = 0; i < aDict.length; ++i)
oDict[aDict[i]] = true;
return oDict;
}
Posted: Fri Nov 20, 2015 4:46 pm
by SFC
KDJ
Thanks for your work.
But as for me I'd like to get instrument. I got its already.
I tested its both scripts.
dictionary = 7838 words = 71,930 b
1.
file1 = 594,032 b = repeated first test many times.
Skif_off's DIC1 = 384 - 395 ms SORTED
KDJ's DIC2 = 419 - 429 ms and result is NOT SORTED
2.
file2 = 56,663,217 b = LDOCE6 xml code
DIC1 = 37877 - 38295 ms
DIC2 = AkelPAD gets into frozen status. maybe it gets loop encircle
maybe for other data...
I set both scripts for use for sorted or non-sorted results AND COMPARE RESULT for mistakes
Thanks
Posted: Sat Nov 21, 2015 6:26 pm
by KDJ
SFC
This version should work faster (with sorting and without sorting):
var nChoice;
var nTime;
var aWordAll;
var aWord;
var oDict;
var i;
nChoice = AkelPad.MessageBox(AkelPad.GetMainWnd(), "Do you want to sort the output words?", WScript.ScriptName, 0x23 /*MB_ICONQUESTION|MB_YESNOCANCEL*/);
if (nChoice == 2 /*IDCANCEL*/)
WScript.Quit();
nTime = new Date().getTime();
if (aWordAll = AkelPad.GetTextRange(0, -1).toLowerCase().match(/[a-z']{2,}/g))
{
aWord = [];
oDict = GetDictionary();
for (i = 0; i < aWordAll.length; ++i)
{
if (! (aWordAll[i] in oDict))
{
aWord.push(aWordAll[i]);
oDict[aWordAll[i]] = true;
}
}
if (nChoice == 6 /*IDYES*/)
aWord.sort();
AkelPad.SetSel(0, -1);
AkelPad.ReplaceSel(aWord.join("\r"), -1);
}
WScript.Echo("Time: " + (new Date().getTime() - nTime) + " ms");
function GetDictionary()
{
var aDict = AkelPad.ReadFile(AkelPad.GetAkelDir(1) + "\\Tools\\dictionary.txt", 0x10 /*OD_ADT_NOMESSAGES*/, 65001 /*UTF-8*/, 0).toLowerCase().split(/[\r\n]+/);
var oDict = {};
var i;
for (i = 0; i < aDict.length; ++i)
oDict[aDict[i]] = true;
return oDict;
}
Posted: Sun Nov 22, 2015 2:30 pm
by SFC
KDJ wrote:This version should work faster
Yes. It is faster in 3 - 5 times !!!
And it processes XML file wo problem now also!!!
Many thanks.
Now I can use two scripts for different purposes
word: con‧ces‧sion‧aire
DIC2 sees this word as 4 different words. It is correct for some cases.
DIC1 sees this word as bad word and ignores. It is correct for some cases also.
Some wish:
Remove ask-dialog for ordered/don't ordered - it is complicated
Make pls (ordered/don't ordered) as parameter of call-script. (1/0 f.ex. default = 1) - without any dialog screens
Thanks for ALL.
Many wishes for ALL
Posted: Sun Nov 22, 2015 4:16 pm
by SFC
very sorrrryy
Corections:
My pre- previous test was wrong
I tested scripts by absent dictionary = there was wrong path to dictionary.txt = there were tests without dictionary for both scripts
Now I test correctly both scripts:
file2 = 56,663,217 b = LDOCE6 xml code
DIC1 = 95000 - 96000 ms
DIC2 = 5500 - 6800 ms
That is right