БлогNot. Все существительные русского языка в простом формате

Все существительные русского языка в простом формате

Готового файла в нужном мне простейшем и удобном формате (простой текст, одно слово - одна строка) не нашёл, пришлось сделать самому.

Для начала я взял "все" слова русского языка с указанием части речи, числа, рода и падежа, то есть, морфологический словарь русского языка по Хагену, вот отсюда (hagen-morph.rar). Развёрнутый файл .txt будет более 200 Мб, так что поосторожней с "Блокнотиками", если его скачаете :)

Потом я простенько отобрал оттуда существительные по формальному указанию файла словаря, вот код на PHP:

<?php
 function startsWith($haystack, $needle) {
  return (substr($haystack, 0, strlen($needle)) === $needle);
 } 

 $f = fopen ('1.txt','r');
 $r = fopen ('2.txt','w');
 if (!f or !$r) halt ('File error');
 $t1 = time ();
 $n = 0;
 while (!feof($f)) {
  $s = fgets($f);
  if (strlen(trim($s))<1 or $s[0]==' ') continue;
  $w = explode ('|',$s);
  if (count($w)<2) continue;
  if (startsWith(trim($w[1]),'сущ')==true) {
   fputs ($r,trim($w[0])."\r\n");
   $n++;
  }
 }
 $t2 = time ();
 fclose ($r);
 fclose ($f);
 echo '<p>'.$n.' word(s) in '.($t2-$t1).' sec.</p>';
?>

Предполагается, что развёрнутый словарь "лежит" под именем 1.txt в папке скрипта, а вывод писался в файл 2.txt.

Символы конца строк - CR/LF, то есть, в формате для Windows. Скрипт может выполняться до 10 секунд, но из-за нехватки памяти "зависать" не должен, так как не пытается засунуть весь файл в оперативку, а читает его построчно.

"Вытащить" только единственное число существительных пришлось вторым маленьким кодом:

<?php
 function endsWith ($haystack, $needle) {
  $length = strlen($needle);
  if ($length == 0) return true;
  return (substr($haystack,-$length) === $needle);
 }

 function pluralForm ($s1, $s2) {
  $s1len = strlen($s1);
  $s2len = strlen($s2);
  if (strncmp($s1,$s2,$s2len-1)==0 and ($s2len == $s1len or $s2len == $s1len+1)) return true; 
  $suffix = array (
   'ек'=>'ки',
   'ец'=>'цы',
   'ец'=>'ьцы',
   'ок'=>'ки',
   'енок'=>'ята',
//   ''=>'',
  );
  foreach ($suffix as $suf1=>$suf2) {
   if (endsWith($s1,$suf1) and endsWith($s2,$suf2)) return true;
  }
  return false;
 } 

 $f = fopen ('2.txt','r');
 $r = fopen ('3.txt','w');
 if (!f or !$r) halt ('File error');
 $t1 = time ();
 $n = 0;
 $s0 = '';
 while (!feof($f)) {
  $s1 = trim(fgets($f));
  if ($s1!=$s0 and pluralForm($s0,$s1)==false) {
   fputs ($r,$s1."\r\n");
   $n++;
  }
  $s0 = $s1;
 }
 $t2 = time ();
 fclose ($r);
 fclose ($f);
 echo '<p>'.$n.' word(s) in '.($t2-$t1).' sec.</p>';
?>

Качество отбора "единственного числа" здесь невысоко, скрипт выполнялся на локальном хосте "Денвер".

Можете исключить из получившегося второго словаря что-то ещё, это легко сделать даже с помощью функций startsWith и endsWith из приведённого кода. Например, вот так можно вывести все слова, заканчивающиеся на "ые":

<?php
 function endsWith ($haystack, $needle) {
  $length = strlen($needle);
  if ($length == 0) return true;
  return (substr($haystack,-$length) === $needle);
 }

 $f = fopen ('3.txt','r');
 if (!f) halt ('File error');
 $n = 0;
 while (!feof($f)) {
  $s = trim(fgets($f));
  if (endsWith($s,'ые')) echo '<br>'.++$n.' '.$s;
 }
 fclose ($f);
?>

В реальности исключать такие слова не стоит, ведь окончание "ие" или "ые" может означать не совсем "множественное число", а что-то вроде "русские как нация", группа "Младшенькие" или отряд "Куриные".

В файлах, разумеется, нет имён, географических названий и т.п. Буквы "ё" тоже нигде нет, как и в исходном словаре.

Скачать файлы .txt в архиве .zip (перекодированы в кодировку utf-8 Юникода!)

 Более 125 тысяч русских существительных в именительном падеже (единственное и множественное число, мужской и женский род) (413 Кб)

 Более 67 тысяч русских существительных в именительном падеже (единственное число, мужской и женский род) (260 Кб)

 Словарь с падежами .txt, примерно 1,5 млн словоформ и 35 Мб в кодировке utf-8

27.01.2017, 13:12 [30237 просмотров]


теги: язык программирование php форматы словарь

показать комментарии (6)