Что-нибудь вроде этого онлайнового агрегата:
http://www.docent777.ru/index/podschjot_slov_v_tekste/0-33 (http://www.docent777.ru/index/podschjot_slov_v_tekste/0-33)
Оный не устраивает меня неприятием слов с нерусскими буквами типа ө, ү. И еще тем, что онлайновый, - боюсь, текст целой книги на 1000 страниц в него запихнуть не получится.
Так что какую-нибудь программку бы, озволяющую пересчитывать огромные объемы в уникодовской кодировке. Найдется такая?
Думаю, для ваших целей лучше всего будет написать её самостоятельно. Так надёжнее будет - не придётся задумываться о том, какие буквы она понимает, а какие нет. Разумеется, для каждого текста надо будет конкретно указывать, какой набор символов считать за буквы, что - за пробельные символы и знаки препинания. Опять же, правила для дефиса и тире, если они в тексте идут или могут идти одним символом. А в чужой программе чего-то наверняка всегда будет не предусмотрено.
Цитата: Toman от октября 6, 2013, 14:05
Думаю, для ваших целей лучше всего будет написать её самостоятельно. Так надёжнее будет - не придётся задумываться о том, какие буквы она понимает, а какие нет. Разумеется, для каждого текста надо будет конкретно указывать, какой набор символов считать за буквы, что - за пробельные символы и знаки препинания. Опять же, правила для дефиса и тире, если они в тексте идут или могут идти одним символом. А в чужой программе чего-то наверняка всегда будет не предусмотрено.
Не хочется заморачиваться с изобретением велосипеда, который наверняка уже в десятках вариантах готовый существует. Тем более, я не программировал уже лет 15, и навыки программирования у меня соответствующие. Программы под Windows делать не умею, поэтому получится у меня работающий под DOSом динозавр, который будет принимать только файлы в формате txt. Так что готовая программа, даже если в ней что-то будет непредусмотрено, наверняка окажется лучше. С дефисами и прочими спорными символами, если понадобится, всегда можно разделаться, поменяв их автозаменой на какую-нибудь кракозябру, которая будет распознаваться так, как нужно.
вот хорошая
www.textcount.com
Цитата: Leo от октября 6, 2013, 14:46
вот хорошая
www.textcount.com
Спасибо! Жаль только, что бесплатная версия тексты длиннее 5000 знаков не принимает.
Цитата: Devorator linguarum от октября 6, 2013, 14:39Программы под Windows делать не умею, поэтому получится у меня работающий под DOSом динозавр, который будет принимать только файлы в формате txt.
Тут, имхо, достаточно скрипта, который будет запускаться в окне браузера.
Функция
split() в javascript принимает регэкспы в роли разделителя, так что проблем быть не должно.
В Microsoft Word встроена статистика для открытого документа.
погрешность подсчёта вордом доходит до 20 %
Вордовская статистика мне не подойдет. Нужно не вручную узнавать статистику для каждого отдельного слова, а получать сразу готовый список всех графических слов с указанием количества употреблений.
Цитата: Devorator linguarum от октября 6, 2013, 15:22
Вордовская статистика мне не подойдет. Нужно не вручную узнавать статистику для каждого отдельного слова, а получать сразу готовый список всех графических слов с указанием количества употреблений.
Может вам тогда традос попробовать ?
Цитата: Devorator linguarum от октября 6, 2013, 14:39
Программы под Windows делать не умею
Цитата: Devorator linguarum от октября 6, 2013, 14:39
поэтому получится у меня работающий под DOSом динозавр
И не надо, ни то, ни другое. Пишите не привязанные к конкретной ОС. Я тоже не умею писать под винду, и не писал под неё, когда под ней работал. Тем не менее, программы для работы с текстами писал и тогда, и, при случае, сейчас. На Перле, хоть и не люблю этот язык - но такие вот нехитрые процедуры с текстом на нём писать быстрее, чем на других языках, кажется. Перл медленный - но для задачи вроде вашей - линейной по длине текста, решаемой за один проход - это не играет существенной роли, если вы не собираетесь прогонять за раз сумасшедшие гигабайты текста.
Цитата: Devorator linguarum от октября 6, 2013, 14:39
который будет принимать только файлы в формате txt
А вот тут вам вряд ли кто поможет. Всякая нормальная программа подсчёта слов будет принимать входной поток только в текстовом формате. Что ж вы ещё хотели? Задача преобразования из чего-то другого в чистый текст - отдельная задача, которую не имеет смысла смешивать с подсчётом. И для этого преобразования существуют отдельные программы, их тьмы.
Цитата: Devorator linguarum от октября 6, 2013, 14:39
С дефисами и прочими спорными символами, если понадобится, всегда можно разделаться, поменяв их автозаменой на какую-нибудь кракозябру
Конкретно дефис/тире можно заменить на пустую строку (т.е. удалить), т.к. это сольёт слова с дефисом в слитные, а в случае тире между словами останутся пробелы, которые не изменят результат подсчёта слов.
Но... хм, так вы и "нерусские буквы", про которые упоминали в начале темы, тоже можете заменить автозаменой на что-нибудь (например, сочетание из русских букв). Тем более, что для подсчёта слов вам не требуется обратимость этого преобразования - так что можно заменять на любое буквосочетание, лишь бы оно оставалось слитным.
Цитата: Leo от октября 6, 2013, 15:23
Цитата: Devorator linguarum от октября 6, 2013, 15:22
Вордовская статистика мне не подойдет. Нужно не вручную узнавать статистику для каждого отдельного слова, а получать сразу готовый список всех графических слов с указанием количества употреблений.
Может вам тогда традос попробовать ?
А что такое традос?
Цитата: Bhudh от октября 6, 2013, 15:09
Тут, имхо, достаточно скрипта, который будет запускаться в окне браузера.
Функция split() в javascript принимает регэкспы в роли разделителя, так что проблем быть не должно.
Это было бы неплохо, и на джаваскрипте писать не менее легко и приятно, чем на перле (если специально не забуриваться в нечитаемый синтаксис). Но, увы, выполнение джаваскрипта в браузере настолько медленно, что не сравнить даже с интерпретатором перла. У меня есть транслитератор на JS, так на любом сколько-нибудь объёмном тексте браузер виснет, и многократно, останавливая выполнение скрипта, спрашивает, хочу ли я продолжить исполнение. То же самое будет и с подсчётом слов. Слишком муторно для пользователя, да и реально дико медленно.
Цитата: Devorator linguarum от октября 6, 2013, 15:24
Цитата: Leo от октября 6, 2013, 15:23
Цитата: Devorator linguarum от октября 6, 2013, 15:22
Вордовская статистика мне не подойдет. Нужно не вручную узнавать статистику для каждого отдельного слова, а получать сразу готовый список всех графических слов с указанием количества употреблений.
Может вам тогда традос попробовать ?
А что такое традос?
Есть такая http://www.sdl.com/de/products/sdl-trados-studio/
она очень многофункциональная (я правда не работал с ней с 2009 года и подзабыл), там есть и бесплатные версии и много вариантов и наворотов. там должно быть и точно вам надо, ибо она подсчитывает fuzzy matches (не помню, как по-русски)
cat tekst.txt | perl kolichestvo_slov.pl
kolichestvo_slov.pl
#!/usr/bin/perl
#cat tekst.txt | perl kolichestvo_slov.pl
#
binmode STDIN, ":utf8";
binmode STDOUT, ":utf8";
binmode(STDERR,":utf8");
use utf8;
use strict;
my $kolichestvo_slov;
my $bukvy = "[йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ-]";
while (<>) {
while ($_ =~ /$bukvy+/g) { $kolichestvo_slov++ }
if ($kolichestvo_slov =~ m/0000$/){
print STDERR "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b $kolichestvo_slov";
}
}
print "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b Итого: $kolichestvo_slov слов.\n";
Цитата: Toman от октября 6, 2013, 15:23
Цитата: Devorator linguarum от октября 6, 2013, 14:39
Программы под Windows делать не умею
Цитата: Devorator linguarum от октября 6, 2013, 14:39
поэтому получится у меня работающий под DOSом динозавр
И не надо, ни то, ни другое. Пишите не привязанные к конкретной ОС. Я тоже не умею писать под винду, и не писал под неё, когда под ней работал. Тем не менее, программы для работы с текстами писал и тогда, и, при случае, сейчас. На Перле, хоть и не люблю этот язык - но такие вот нехитрые процедуры с текстом на нём писать быстрее, чем на других языках, кажется. Перл медленный - но для задачи вроде вашей - линейной по длине текста, решаемой за один проход - это не играет существенной роли, если вы не собираетесь прогонять за раз сумасшедшие гигабайты текста.
Цитата: Devorator linguarum от октября 6, 2013, 14:39
который будет принимать только файлы в формате txt
А вот тут вам вряд ли кто поможет. Всякая нормальная программа подсчёта слов будет принимать входной поток только в текстовом формате. Что ж вы ещё хотели? Задача преобразования из чего-то другого в чистый текст - отдельная задача, которую не имеет смысла смешивать с подсчётом. И для этого преобразования существуют отдельные программы, их тьмы.
Цитата: Devorator linguarum от октября 6, 2013, 14:39
С дефисами и прочими спорными символами, если понадобится, всегда можно разделаться, поменяв их автозаменой на какую-нибудь кракозябру
Конкретно дефис/тире можно заменить на пустую строку (т.е. удалить), т.к. это сольёт слова с дефисом в слитные, а в случае тире между словами останутся пробелы, которые не изменят результат подсчёта слов.
Но... хм, так вы и "нерусские буквы", про которые упоминали в начале темы, тоже можете заменить автозаменой на что-нибудь (например, сочетание из русских букв). Тем более, что для подсчёта слов вам не требуется обратимость этого преобразования - так что можно заменять на любое буквосочетание, лишь бы оно оставалось слитным.
В общем, такой путь решения я в качестве запасного уже обдумывал. Назаменять нерусские буквы на диграфы, нарезать большие объемы текста на куски приемлемой длимны и прогнать хоть через тот онлайновый счетчик, ссылку на который я в первом посте давал.
Или написать-таки в паскале или бейсике безвиндоузного динозара и загонять в него тексты, предварительно пересохраненные в txt хоть через ворд.
С Перлом никогда не работал, поэтому использование его исключается. Осваивать новый язык программирования ради написания одной маленькой программы смысла нет.
А, чёрт, кажется, я неправильно понял задачу. Т.е. вам нужен не подсчёт слов (неважно каких), а подсчёт числа конкретных графических словоформ? Но с критерием границы слова, соответствующим письменности языка. Тогда джаваскрипт точно отпадает напрочь, т.к. эта задача уже значительно тяжелее вычислительно, и браузер на ней просто вообще убьётся.
А Перл как раз подойдёт, наверное - я сам делал на нём такую программу (но только без критерия границы слова - она составляла словарь встречаемости тупо из подстрок определённой длины, а не из слов в буквальном смысле). Но принципиальной разницы нет, с точки зрения сложности. Перл справится.
Цитата: Devorator linguarum от октября 6, 2013, 15:32
С Перлом никогда не работал, поэтому использование его исключается. Осваивать новый язык программирования ради написания одной маленькой программы смысла нет.
Цитата: Toman от октября 6, 2013, 15:34Но с критерием границы слова, соответствующим письменности языка.
Освойте программу приведенную выше, и замените набор букв на тот который вам нужен в строке:
my $bukvy = "[йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ-]";
Границы как раз и будут все те знаки которые не буквы. В примере в конце указан дефис, можно убрать его, но в данной строке он обязательно должен стоять в конце после остальных букв если нужен.
Цитата: Toman от октября 6, 2013, 15:34
А, чёрт, кажется, я неправильно понял задачу. Т.е. вам нужен не подсчёт слов (неважно каких), а подсчёт числа конкретных графических словоформ? Но с критерием границы слова, соответствующим письменности языка.
Да зачем такие сложности с границей слова? Критерии стандартные: пробел, конец строки, знаки препинания, кавычки. Алфавиты - только кириллица и латиница с дополнительными диакритизированными буквами. Деванагари или японскую кану обрабатывать не планируется.
Цитата: Devorator linguarum от октября 6, 2013, 15:32
Или написать-таки в паскале или бейсике безвиндоузного динозара
А, ну в этом смысле на перле будет такой же "безвиндоузный". Т.е. консольная программа, вызываемая из командной строки (или пакетного файла/шелл-скрипта).
Цитата: Devorator linguarum от октября 6, 2013, 15:32
предварительно пересохраненные в txt хоть через ворд
Предварительно пересохранять в текст в любом случае придётся, другого разумного пути.
Цитата: Devorator linguarum от октября 6, 2013, 15:32
С Перлом никогда не работал, поэтому использование его исключается. Осваивать новый язык программирования ради написания одной маленькой программы смысла нет.
Почему же только одной? Вполне вероятно, пригодится ещё неоднократно. И я же не предлагаю осваивать его полностью (чего я и сам ни за что не подумаю делать: с точки зрения полного освоения Перл - пожалуй, один из самых сложных языков среди практически применяемых, м.б. даже вообще самый сложный - хотя м.б. с ним в сложности соперничает Вижуал Бейсик, но его я совершенно не знаю), я предлагаю воспользоваться лишь его простейшими средствами, в рамках которых его синтаксис более-менее нормальный, не слишком шокирующий. Хотя... хотя да, это он для "сишников" более-менее привычный, а вы-то, получается, скорее "паскальщик"...
В общем, чтобы было понятнее, конкретный пример: нужно посчитать количество употреблений всех разных графических слов в "Войне и мире" на калмыцком языке. Или на чукотском. Морфологию учитывать не нужно, так что нүдн и нүднд будут считаться за разные слова.
Цитата: Toman от октября 6, 2013, 15:44
Хотя... хотя да, это он для "сишников" более-менее привычный, а вы-то, получается, скорее "паскальщик"...
Я вообще "бейсикщик". В паскале тоже приходилось работать, так что с ним справлюсь, но это уже не от хорошей жизни, а если в бейсике средств не хватает.
Цитата: Devorator linguarum от октября 6, 2013, 15:48
В общем, чтобы было понятнее, конкретный пример: нужно посчитать количество употреблений всех разных графических слов в "Войне и мире" на калмыцком языке. Или на чукотском. Морфологию учитывать не нужно, так что нүдн и нүднд будут считаться за разные слова.
Подсчитывать символы или слова? Вообще количество слов или сколько раз каждое слово присутствует в тексте? Все это разные задачи. Определитесь.
Цитата: Toman от октября 6, 2013, 15:28У меня есть транслитератор на JS, так на любом сколько-нибудь объёмном тексте браузер виснет
:o
Простите, а что для Вас "объёмный текст"⁈
Мой транслитератор древнегреческого в латиницу (причём не с одним прогоном) Илиаду+Одиссею только что транслитерировал за
4,5 секунды.
Цитата: Славен от октября 6, 2013, 15:55Вообще количество слов или сколько раз каждое слово присутствует в тексте?
Цитата: Devorator linguarum от октября 6, 2013, 15:22получать сразу готовый список всех графических слов с указанием количества употреблений
Цитата: Славен от октября 6, 2013, 15:36
Освойте программу приведенную выше, и замените набор букв на тот который вам нужен
Ваша программа считает слова общей кучей, т.е. выдаёт результат в виде одного числа. А насколько я понял из одной фразы топикстартера, на выходе нужен вовсе даже словарь встречаемости с числом вхождений каждой найденной в тексте словоформы. Так что такая простая программа всё же не годится. А как раз для словарей в Перле есть удобное синтаксическое средство - "хеши" - так там называются собственно словари.
Цитата: Devorator linguarum от октября 6, 2013, 15:43
Да зачем такие сложности с границей слова? Критерии стандартные: пробел, конец строки, знаки препинания, кавычки.
Никаких сложностей - я именно это и имел в виду. Я просто к тому, что в существующем виде моя программа и эти критерии игнорирует, а вместо этого берёт подстроки заданной заранее длины, поэтому прямо в этом виде она вам не подойдёт.
Но если интересно, можете посмотреть её, она тоже маленькая (а могла бы быть ещё меньше, если бы не подразумевала каких-то дальнейших планов, суть которых я уже не помню, но уши которых торчат в закомментированном фрагменте):
#!/usr/bin/perl
$max_word_size=4;
while(<STDIN>){
$text.=$_;
}
$len=length($text);
for($s=1;$s<=$max_word_size;++$s){
for($i=0;$i<=($len-$s);++$i){
$subs=substr($text,$i,$s);
# $parent_subs=substr($subs,0,$s-1);
# if($parent_subs eq ''){
# $parent_subs="\'";
# }
# $wl{$parent_subs}.="\t$subs";
++$wc{$subs};
}
}
@hkeys=keys %wc;
@standart_sorted_keys= sort @hkeys;
foreach $k (@standart_sorted_keys){
(length($k)==$max_word_size) && (print $k."\t".$wc{$k}."\n");
}
Цитата: Bhudh от октября 6, 2013, 16:02
Простите, а что для Вас "объёмный текст"⁈
Да хотя бы даже одна страница текста.
Цитата: Bhudh от октября 6, 2013, 16:02
Мой транслитератор древнегреческого в латиницу (причём не с одним прогоном) Илиаду+Одиссею только что транслитерировал за 4,5 секунды.
Браузерный, на джаваскрипте? Ну, значит, это я так криво написал, наверное. Или правила транслитерации алгоритмически слишком сложны оказались.
Цитата: Toman от октября 6, 2013, 16:28Браузерный, на джаваскрипте?
Браузерный, на джаваскрипте, не шибко-то оптимизированный.
var greekTrplDiphthongsI = "αἰεἰοἰαἱεἱοἱαἲεἲοἲαἳεἳοἳαἴεἴοἴαἵεἵοἵαἶαἷεἶεἷοἶοἷυἰυἱυἲυἳυἴυἵυἶυἷΑἰΕἰΟἰΑἱΕἱΟἱΑἲΕἲΟἲΑἳΕἳΟἳΑἴΕἴΟἴΑἵΕἵΟἵΑἶΑἷΕἶΕἷΟἶΟἷΥἰΥἱΥἲΥἳΥἴΥἵΥἶΥἷ";
var latinTrplDiphthongsI = "ˀaiˀeeˀoihaiheehoiˀaìˀeèˀoìhaìheèhoìˀaíˀeéˀoíhaíheéhoíˀáiháiˀéehéeˀóihóiˀuihuiˀuìhuìˀuíhuíˀúihúiˀaiˀeeˀoihaiheehoiˀaìˀeèˀoìhaìheèhoìˀaíˀeéˀoíhaíheéhoíˀáiháiˀéehéeˀóihóiˀuihuiˀuìhuìˀuíhuíˀúihúi";
var greekTrplDiphthongsU = "αὐεὐοὐαὑεὑοὑαὒεὒοὒαὓεὓοὓαὔεὔοὔαὕεὕοὕαὖαὗεὖεὗοὖοὗγχ";
var latinTrplDiphthongsU = "ˀauˀeuˀoohauheuhooˀaùˀeùˀoòhaùheùhoòˀaúˀeúˀoóhaúheúhoóˀáuháuˀéuhéuˀóóhóóŋkʰ";
var greekDblDiphthongs = "αῖεῖοῖαῦεῦοῦειεὶείουοὺούγγγκ";
var latinDblDiphthongs = "áiéeóiáuéuóoeeeèeéoooòoóŋɡŋk";
var greekQuadPolyLetters = "ᾆᾇᾎᾏᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾞᾟᾠᾡᾢᾣᾤᾥᾦᾧᾨᾩᾪᾫᾬᾭᾮᾯ";
var latinQuadTrans = "ˀáaiháaiˀáaiháaiˀææihææiˀæǣihæǣiˀæǽihæǽiˀǽæihǽæiˀææihææiˀæǣihæǣiˀæǽihæǽiˀǽæihǽæiˀwwihwwiˀwẁihwẁiˀwẃihwẃiˀẃwihẃwiˀwwihwwiˀwẁihwẁiˀwẃihwẃiˀẃwihẃwi";
var greekTrplPolyLetters = "ᾂᾃᾄᾅἆἇᾀᾁᾷᾊᾋᾌᾍἎἏᾈᾉἠἡἢἣἤἥἦἧῃῂῄῇἨἩἪἫἬἭἮἯῌἶἷἾἿὖὗὟὠὡὢὣὤὥῳῲῴῷὦὧὨὩὪὫὬὭὮὯῼ";
var latinTrplTrans = "ˀàihàiˀáiháiˀáaháaˀaihaiáaiˀàihàiˀáiháiˀáaháaˀaihaiˀææhææˀæǣhæǣˀæǽhæǽˀǽæhǽæææiæǣiæǽiǽæiˀææhææˀæǣhæǣˀæǽhæǽˀǽæhǽæææiˀíihíiˀíihíiˀúuhúuhúuˀwwhwwˀwẁhwẁˀwẃhwẃwwiwẁiwẃiẃwiˀẃwhẃwˀwwhwwˀwẁhwẁˀwẃhwẃˀẃwhẃwwwi";
var greekDblPolyLetters = "ἀἁἂἃἄἅᾶᾳᾲᾴἈἉἊἋἌἍᾼἐἑἒἓἔἕἘἙἚἛἜἝηὴήῆΗῊΉἰἱἲἳἴἵῖῗἸἹἺἻἼἽὀὁὂὃὄὅὈὉὊὋὌὍῤῥῬὐὑὒὓὔὕῦῧὙὛὝωὼώῶΩῺΏ";
var latinDblTrans = "ˀahaˀàhàˀáhááaaiàiáiˀahaˀàhàˀáháaiˀeheˀèhèˀéhéˀeheˀèhèˀéhéæææǣæǽǽææææǣæǽˀihiˀìhìˀíhííiíiˀihiˀìhìˀíhíˀohoˀòhòˀóhóˀohoˀòhòˀóhóʰrrhhrˀuhuˀùhùˀúhúúuúuhuhùhúwwwẁwẃẃwwwwẁwẃ";
var greekMonoPolyLetters = "ὰάᾺΆὲέῈΈὶίῒΐῚΊὸόῸΌὺύῢΰῪΎάέήίϊΐόύϋΰώΆΈΉΊΌΎΏᾰᾱῐῑῠῡ·"; //θΘφΦχΧ
var latinMonoTrans = "àáàáèéèéìíìíìíòóòóùúùúùúáéǽíiíóúuúẃáéǽíóúẃăāĭīŭū,";
var greekLetters = "αβγδεζικλμνξοπρςστυψΑΒΓΔΕΖΙΚΛΜΝΞΟΠΡΣΤΥΨ";
var latinLetters = "abɡdeziklmnšoprsstučabɡdeziklmnšoprstuč";
var greekbr = "\n";
function grk2tr(str) {
var ms_start = new Date().getTime();
str = str.replace(RegExp(greekbr,'g'),'<br />');
str = str.replace(RegExp('[0-9]+([^\). ])','g'),'$1');
str = str.replace(RegExp('(', |᾽, |' |᾽ |'|᾽)','g'),'');
for (var i=0,l=0; i < greekTrplDiphthongsI.length; i+=2,l+=3) {
str = str.replace(RegExp(greekTrplDiphthongsI.substr(i,2),'gi'),latinTrplDiphthongsI.substr(l,3));
}
for (var i=0,l=0; i < greekTrplDiphthongsU.length; i+=2,l+=3) {
str = str.replace(RegExp(greekTrplDiphthongsU.substr(i,2),'gi'),latinTrplDiphthongsU.substr(l,3));
}
for (var i=0,l=0; i < greekDblDiphthongs.length; i+=2,l+=2) {
str = str.replace(RegExp(greekDblDiphthongs.substr(i,2),'gi'),latinDblDiphthongs.substr(l,2));
}
for (var i=0,l=0; i < greekQuadPolyLetters.length; i++,l+=4) {
str = str.replace(RegExp(greekQuadPolyLetters[i],'gi'),latinQuadTrans.substr(l,4));
}
for (var i=0,l=0; i < greekTrplPolyLetters.length; i++,l+=3) {
str = str.replace(RegExp(greekTrplPolyLetters[i],'gi'),latinTrplTrans.substr(l,3));
}
for (var i=0,l=0; i < greekDblPolyLetters.length; i++,l+=2) {
str = str.replace(RegExp(greekDblPolyLetters[i],'gi'),latinDblTrans.substr(l,2));
}
for (var i=0; i < greekMonoPolyLetters.length; i++) {
str = str.replace(RegExp(greekMonoPolyLetters[i],'gi'),latinMonoTrans[i]);
}
for (var i=0; i < greekLetters.length; i++) {
str = str.replace(RegExp(greekLetters[i],'gi'),latinLetters[i]);
}
str = str.replace(RegExp('[θΘ]','g'),'tʰ');
str = str.replace(RegExp('[φΦ]','g'),'pʰ');
str = str.replace(RegExp('[χΧ]','g'),'kʰ');
str = str.replace(RegExp('ǣ','g'),'æ̀');
str = str.replace(RegExp('ẃ','g'),'ɔ́');
str = str.replace(RegExp('ẁ','g'),'ɔ̀');
str = str.replace(RegExp('w','g'),'ɔ');
str = str.replace(RegExp('š','g'),'ks');
str = str.replace(RegExp('š','g'),'x');
str = str.replace(RegExp('č','g'),'ps');
var ms_stop = new Date().getTime();
alert(ms_stop-ms_start);
return str;
}
Цитата: Bhudh от октября 6, 2013, 16:34
Браузерный, на джаваскрипте, не шибко-то оптимизированный.
Ой, какой малюсенький, на регекспах-то! Свой я тоже хотел в сообщение запихать - да не смог, ограничение размера сообщения не позволяет.
Могу вставить, для примера, только часть - только из латиницы в кириллицу. Регекспами воспользоваться, конечно, можно было бы. Но не знаю, удобно ли.
var cyr_letters_small= new Array
("а","б","в","г","д","е","ё","ж","з","и","й","к","л","м","н","о","п","р","с","т",
"у","ф","х","ц","ч","ш","щ","ъ","ы","ь","э","ю","я");
var cyr_letters_cap= new Array
("А","Б","В","Г","Д","Е","Ё","Ж","З","И","Й","К","Л","М","Н","О","П","Р","С","Т",
"У","Ф","Х","Ц","Ч","Ш","Щ","Ъ","Ы","Ь","Э","Ю","Я");
var lat_letters_small= new Array
("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t",
"u","v","w","x","y","z");
var lat_letters_cap= new Array
("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T",
"U","V","W","X","Y","Z");
var in_arr;
function lat2cyr_output(){
t_out=document.rustranslit.text_out;
t_out.value="";
preform_in_arr();
for(var i=0;in_arr[i];++i){
lat2cyr_index(i);
adjust_result_ucase_index(i);
t_out.value+=in_arr[i].result;
}
}
function cyr2lat_output(){
t_out=document.rustranslit.text_out;
t_out.value="";
preform_in_arr();
for(var i=0;in_arr[i];++i){
cyr2lat_index(i);
adjust_result_ucase_index(i);
t_out.value+=in_arr[i].result;
}
}
function preform_deinsect(){
t_out=document.rustranslit.text_out;
preform_in_arr();
for(var i=0;in_arr[i];++i){
lat2cyr_index(i);
adjust_result_ucase_index(i);
}
for(var i=0;rec=in_arr[i];++i){
t_out.value+=(rec.original_char+' ');
t_out.value+=(rec.printable_class+' ');
t_out.value+=(rec.ucase+' ');
t_out.value+=(rec.letterclass+' ');
t_out.value+=(rec.cyr_letter+' ');
t_out.value+=(rec.lat_letter+' ');
t_out.value+=(rec.result);
t_out.value+=('\n');
}
}
function preform_in_arr(){
t_in=document.rustranslit.text_in;
in_arr=new Array;
for(var i=0;lett=t_in.value.substr(i,1);++i){
in_arr[i]=new Object;
preform_rec(in_arr[i],lett);
}
}
function preform_rec(rec,c){
rec.original_char=c;
rec.printable_class=get_char_printable_class(c);
rec.ucase=get_char_ucase(c);
rec.letterclass=get_char_letterclass(c);
rec.cyr_letter=get_char_cyr_letter(c);
rec.lat_letter=get_char_lat_letter(c);
}
function adjust_result_ucase_index(index){
var rec=in_arr[index];
if(rec.result==''&&rec.ucase==1){
if(in_arr[index+1].letterclass=='C'||in_arr[index+1].letterclass=='L'){
in_arr[index+1].ucase=1;
}
}
if((rec.letterclass!='C')&&(rec.letterclass!='L')) return;
var post1=index<=(in_arr.length-2)?in_arr[index+1]:0;
rec_ucase=rec.ucase;
post_ucase=post1?post1.ucase:-1;
var ucase_type="bb";
if(rec_ucase==1){
if(post_ucase==0){
ucase_type="Bb";
}else{
ucase_type="BB";
}
}
var res_new='';
for(var p=0;p<rec.result.length;++p){
var c=rec.result.substr(p,1);
for(var i=0;cyr_letters_small[i]||lat_letters_small[i];++i){
if( c==cyr_letters_small[i]){
res_new+=(ucase_type=='BB')||(ucase_type=='Bb'&&p==0)?cyr_letters_cap[i]:c;
}else if(c==lat_letters_small[i]){
res_new+=(ucase_type=='BB')||(ucase_type=='Bb'&&p==0)?lat_letters_cap[i]:c;
}
}
}
rec.result=res_new;
}
function lat2cyr_index(index){
var rec=in_arr[index];
var pre3=index>=3?in_arr[index-3]:0;
var pre2=index>=2?in_arr[index-2]:0;
var pre1=index>=1?in_arr[index-1]:0;
var post1=index<=(in_arr.length-2)?in_arr[index+1]:0;
var post2=index<=(in_arr.length-3)?in_arr[index+2]:0;
var post3=index<=(in_arr.length-4)?in_arr[index+3]:0;
var j_post_regvowel=false;
var j_post_iy=false;
var j_pre_regvowel_j=false;
var j_pre_jercondition=false;
switch (rec.lat_letter){ // letters here only lowercase!
case 'a':
switch(pre1.lat_letter){
case 'i':
case 'j':
rec.result='я';return;
default:
rec.result='а';return;
}
case 'b':
rec.result='б';return;
case 'c':
switch(post1.lat_letter){
case 'h':
rec.result='ч';return;
default:
rec.result='дж';return;
}
case 'd':
switch(post1.lat_letter){
case 'h':
rec.result='дз';return;
default:
rec.result='д';return;
}
case 'e':
switch(pre1.lat_letter){
case 'i':
case 'j':
rec.result='е';return;
default:
rec.result='э';return;
}
case 'f':
rec.result='ф';return;
case 'g':
switch(post1.lat_letter){
case 'h':
rec.result='гх';return;
case 'q':
rec.result='гъ';return;
default:
rec.result='г';return;
}
case 'h':
rec.result='';return;
case 'i':
switch(pre1.lat_letter){
case 'y':
case 'i':// only second 'i' yields russian cyrillic 'i'
case 'j':// 'ji' - in Russian there isn't such a letter, while in Ukrainian it is :)
rec.result='и';return;
// consonants and pseudoconsonants accepting "yeri"
case 'b':
case 'c':
case 'd':
case 'f':
case 'g':
case 'h':
case 'k':
case 'l':
case 'm':
case 'n':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'v':
case 'w':
case 'x':
case 'z':
default: // if one set single 'i' where it shouldn't stay,
// he get maybe some crazy results...
switch(post1.lat_letter){
// vowel
case 'a':// "..bia.."
case 'e':// "..bie.."
case 'o':// "..bio.."
case 'u':// "..biu.." - all null
case 'i':// "..bii.." - also null for the first 'i'
rec.result='';return;
case 'y':// "..biy.." - incorrect at all, but what to do.. We should translit it as incorrect as one has written it :)
default:
rec.result='ь';return;
}
}
case 'j':// the most complex letter!
// It must be omitted if it stays in patterns such as "bije", "biji(y)",
// "byje", "byji(y)", "eje", " je", but should not be omitted in patterns
// such as "*jb", "bj*", " ji(y)", "eji(y)"
// So, at first threat "*jb" situation
switch (post1.lat_letter){
case 'i':
case 'y':
j_post_iy=true;break;
case 'a':
case 'e':
case 'o':
case 'u':
j_post_regvowel=true;break;
case 'j':// 'j' here is also a consonant
case 'b':
case 'c':
case 'd':
case 'f':
case 'g':
case 'h':
case 'k':
case 'l':
case 'm':
case 'n':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'v':
case 'w':
case 'x':
case 'z':
default:
rec.result='й';return;
}
switch(pre1.lat_letter){
case 'b':// here 'j' will not be used as consonant!
case 'c':
case 'd':
case 'f':
case 'g':
case 'h':
case 'k':
case 'l':
case 'm':
case 'n':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'v':
case 'w':
case 'x':
case 'z':
rec.result='й';return;
case 'i':
case 'y':
switch(pre2.lat_letter){
case 'b':// here 'j' will also not be used as normal consonant!
case 'c':
case 'd':
case 'f':
case 'g':
case 'h':
case 'k':
case 'l':
case 'm':
case 'n':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'v':
case 'w':
case 'x':
case 'z':
j_pre_jercondition=true;break;
case 'j':
case 'i':
case 'y':
case 'a':// this is also incorrect, but...
case 'e':
case 'o':
case 'u':
default:
j_pre_regvowel_j=true;break;
} break;
case 'j':
case 'a':
case 'e':
case 'o':
case 'u':
default:// empty space is equal to regular vowel before 'j'
j_pre_regvowel_j=true;break;
}
if(j_post_regvowel){
if(j_pre_regvowel_j){
rec.result='';return;
}else if(j_pre_jercondition){
rec.result='';return;
}else{
rec.result='й';return;
}
}else if(j_post_iy){
if(j_pre_regvowel_j){
rec.result='й';return;
}else if(j_pre_jercondition){
if(post1.lat_letter=='y'){
rec.result='й';return;
}else{
rec.result='';return;
}
}else{
rec.result='й';return;
}
}else{
rec.result='й';return;
}
case 'k':
switch(post1.lat_letter){
case 'q':
rec.result='къ';return;
default:
rec.result='к';return;
}
case 'l':
rec.result='л';return;
case 'm':
rec.result='м';return;
case 'n':
rec.result='н';return;
case 'o':
switch(pre1.lat_letter){
case 'i':
case 'j':
rec.result='ё';return;
default:
rec.result='о';return;
}
case 'p':
rec.result='п';return;
case 'q':
switch(pre1.lat_letter){
case 'k':
case 'g':
case 'x':
rec.result='';return;
default:
rec.result='къ';return;
}
case 'r':
rec.result='р';return;
case 's':
switch(post1.lat_letter){
case 'h':
switch(post2.lat_letter){
case 'h':
rec.result='щ';return;
default:
rec.result='ш';return;
}
default:
rec.result='с';return;
}
case 't':
switch(post1.lat_letter){
case 'h':
rec.result='ц';return;
default:
rec.result='т';return;
}
case 'u':
switch(pre1.lat_letter){
case 'i':
case 'j':
rec.result='ю';return;
default:
rec.result='у';return;
}
case 'v':
rec.result='в';return;
case 'w':
rec.result='w';return;
case 'x':
switch(post1.lat_letter){
case 'q':
rec.result='хъ';return;
case 'h':
rec.result='h';return;
default:
rec.result='х';return;
}
rec.result='х';return;
case 'y':
switch(pre1.lat_letter){
case 'y':
case 'i':// it's wild, but we will do it is such a manner!
case 'j':// 'jy' - in Russian there isn't such a letter
rec.result='ы';return;
// consonants and pseudoconsonants accepting "yer"
case 'b':
case 'c':
case 'd':
case 'f':
case 'g':
case 'h':
case 'k':
case 'l':
case 'm':
case 'n':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'v':
case 'w':
case 'x':
case 'z':
default: // if one set single 'y' where it shouldn't stay,
// he get maybe some crazy results...
switch(post1.lat_letter){
case 'y':// "..byy.."
rec.result='';return;
default:
rec.result='ъ';return;
}
}
case 'z':
switch(post1.lat_letter){
case 'h':
rec.result='ж';return;
default:
rec.result='з';return;
}
default: // not a latin letter
rec.result=rec.cyr_letter||rec.original_char;return;
}
}
function get_char_printable_class(c){
for(var i=0;cyr_letters_cap[i];++i){
if( c==cyr_letters_cap[i]) return 'C';
}
for(var i=0;cyr_letters_small[i];++i){
if( c==cyr_letters_small[i]) return 'c';
}
for(var i=0;lat_letters_cap[i];++i){
if( c==lat_letters_cap[i]) return 'L';
}
for(var i=0;lat_letters_small[i];++i){
if( c==lat_letters_small[i]) return 'l';
}
return 'N';
}
function get_char_ucase(c){
for(var i=0;cyr_letters_cap[i];++i){
if( c==cyr_letters_cap[i]) return 1;
}
for(var i=0;cyr_letters_small[i];++i){
if( c==cyr_letters_small[i]) return 0;
}
for(var i=0;lat_letters_cap[i];++i){
if( c==lat_letters_cap[i]) return 1;
}
for(var i=0;lat_letters_small[i];++i){
if( c==lat_letters_small[i]) return 0;
}
return -1;
}
function get_char_letterclass(c){
for(var i=0;cyr_letters_cap[i];++i){
if( c==cyr_letters_cap[i]) return 'C';
}
for(var i=0;cyr_letters_small[i];++i){
if( c==cyr_letters_small[i]) return 'C';
}
for(var i=0;lat_letters_cap[i];++i){
if( c==lat_letters_cap[i]) return 'L';
}
for(var i=0;lat_letters_small[i];++i){
if( c==lat_letters_small[i]) return 'L';
}
return 'N';
}
function get_char_cyr_letter(c){
for(var i=0;cyr_letters_cap[i];++i){
if( c==cyr_letters_cap[i]) return cyr_letters_small[i];
}
for(var i=0;cyr_letters_small[i];++i){
if( c==cyr_letters_small[i]) return cyr_letters_small[i];
}
}
function get_char_lat_letter(c){
for(var i=0;lat_letters_cap[i];++i){
if( c==lat_letters_cap[i]) return lat_letters_small[i];
}
for(var i=0;lat_letters_small[i];++i){
if( c==lat_letters_small[i]) return lat_letters_small[i];
}
}
(http://www.kolobok.us/smiles/madhouse/russian_roulette.gif)
Думаете, был существенно более простой вариант реализовать ту же функциональность?
Цитата: Toman от октября 6, 2013, 17:40Думаете, был существенно более простой вариант реализовать ту же функциональность?
1) В моём коде ровно та же функциональность. Достаточно поменять строки.
2) Судя по
велосипеду коду, Вам ничего неизвестно про оператор
in (http://www.fpublisher.ru/documentation/javascript_doc/js04.docs#ref3474).
Цитата: Bhudh от октября 6, 2013, 17:51
1) В моём коде ровно та же функциональность. Достаточно поменять строки.
Вы уверены в этом? Впрочем, да, теоретически так сделать, разумеется, можно - но вот только проблема - какова будет длина этих строк? Изначально-то я хотел тоже примерно так поступить - точнее, просто стырить код с сайта translit.ru, и подсунуть туда свои сочетания вместо ихних. Ан нет, не получилось. Таблица простых замен получилась бы монструозной - ещё больше моего транслитератора (и, вероятно, больше любого текста, подлежащего транслитерации), и для генерации этой таблицы всё равно пришлось бы писать вспомогательную программу.
Цитата: Bhudh от октября 6, 2013, 17:51
2) Судя по велосипеду коду, Вам ничего неизвестно про оператор in.
Для чего вы предлагали бы его применить в этом коде??? Вы предлагаете кодировать фактически булевы переменные посредством существования или несуществования у объекта свойства с некоторым именем??? Но это выглядело бы как какой-то изврат, имхо, трудночитаемый. Или для проверки границ массива? Но и там это не дало бы никакого существенного сокращения кода. Вот если бы надо было составлять словарь (что как раз хочет топикстартер), то операции а-ля перловый хеш бы реально пригодились. Но у меня ж тут нет словарей.
элемент in массив, не?
Цитата: arseniiv от октября 6, 2013, 18:23
элемент in массив, не?
Индекс_элемента in массив. Ну и что нам с него толку? Массив[индекс_элемента] даёт (в конкретно моём случае - где нет значимых нулей или пустых строк в массиве) такой же годный логический результат на предмет того, есть ли в массиве (ненулевой) элемент под таким-то номером.
Цитата: Toman от октября 6, 2013, 18:38Индекс_элемента in массив.
Ключ_элемента in объект. Для массива оператор
in не сработает.
Ладно, другое.
function makePredicate(list) {
var d = {};
var len = list.length;
for (i = 0; i < len; i++)
d[list] = true;
function predicate(elem) {
return d[elem];
}
return predicate;
}
Использование:
var isCapital = makePredicate("ABCDEFG...")
// ...
... isCapital(c) ...
Это работает, по крайней мере, быстрее, чем циклы по массивам.
Цитата: Bhudh от октября 6, 2013, 19:00
Для массива оператор in не сработает.
По вашей же ссылке прямым текстом написано, что сработает. Вообще, НЯП, в джаваскрипте каких-то отдельных массивов нет, они такие же "объекты", как и прочие. Просто в качестве ключей при создании используются целые числа.
Цитата: Toman от октября 6, 2013, 19:08По вашей же ссылке прямым текстом написано, что сработает.
А, это я не так выразился. Не сработает поиск значения как ключа, бо ключ там как раз число.
Цитата: Toman от октября 6, 2013, 19:08Вообще, НЯП, в джаваскрипте каких-то отдельных массивов нет, они такие же "объекты", как и прочие.
Не совсем такие же.
Конструктор Array() что-то там переопределяет, ту же
toString(), к примеру.
Цитата: arseniiv от октября 6, 2013, 19:06
Это работает, по крайней мере, быстрее, чем циклы по массивам.
Вот в частности за это я не люблю джаваскрипт. Всё-таки нормальные массивы должны быть. И если бы они были, перебор сравнительно короткого массива на равенство строк имел бы шансы быть не медленнее, чем поиск по ключу. А так, когда даже доступ к каждому элементу массива работает через тот же поиск по ключу - конечно, перебор массива будет медленнее, чем один поиск по ключу.
С одной стороны, такое вот единообразие всех объектов - оно вроде и красиво (и за это мне джаваскрипт нравится), но вот даже не портя этого, можно было бы организовать правильный быстрый доступ по целочисленным ключам без какого-либо поиска - тогда существенных потерь времени на это не было бы. Даже если в 3 раза медленнее поиска по ключу - но всё-таки не в 100 раз медленнее.
Конечно, если бы у меня была привычка в джаваскрипте работать с объектами как с перловскими хешами/словарями и воспринимать их в первую очередь именно как словари, я бы, вполне возможно, так и сделал. Но такой привычки, по крайней мере, в то время, когда был написан этот скрипт (а это было примерно время моего первого появления на ЛФ), у меня не было.
Text::Statistics::Cyrillic creates a seven column CSV file output with one line each token per text given as input a corpus that files names follows ' 1 (1). txt', '1 (2). txt', ..., '1 (n).txt' or 1 \(([1-9]|[1-9][0-9]+)\)\.txt Columns stores statistical information: (1) number of word forms in document d; (2) number of tokens in d; (3) Id number of d, ie., n; (4) frequency of term t in d; (5) corpus frequency of t ; (6) document frequency of t (number of documents where t occurs at least once); (7) t, UTF8 latin coded token-string
https://metacpan.org/module/Text::Statistics::Cyrillic
yatea - Perl script for extracting terms from a corpus of texts and providing a syntactic analysis in a head-modifier representation.
https://metacpan.org/module/THHAMON/Lingua-YaTeA-0.622/bin/yatea
http://neon.niederlandistik.fu-berlin.de/en/textstat/
Автор, если еще актуально :-\, есть программа которой сама пользуюсь - SimWordSorter, она вытаскивает из текста частоту используемых слов, делает отчет по ним, правда она меня полностью не удовлетворяет, так как хотелось бы чтобы поиск производился по корню слова, однако, как видно, таких программ еще не придумали. Но в принципе, это решаемо посредством автосортировки отчетных данных в экселе. Есть еще программа для писателей ywriter5 - там тоже есть функция подсчета повторяемости слов
Цитата: Morugesso от декабря 1, 2013, 12:40
так как хотелось бы чтобы поиск производился по корню слова, однако, как видно, таких программ еще не придумали.
Для этого существуют лемматизаторы.