Advertisement
Guest User

Untitled

a guest
Mar 21st, 2019
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.35 KB | None | 0 0
  1.  
  2. import re
  3. from pymystem3 import Mystem
  4. import time
  5. import os
  6. import csv
  7. import functools
  8. from os.path import isfile, join
  9. from pymystem3 import Mystem
  10. import sys
  11.  
  12. sys.path.append("./")
  13. import rmaker
  14.  
  15. def lemmatize(text):
  16. """
  17. Приведение к нормальной форме.
  18. """
  19.  
  20. m = Mystem()
  21. temp_res = m.lemmatize(text)
  22. return clean_list(temp_res)
  23.  
  24.  
  25. def get_lemma(word):
  26. pos = word.find(':')
  27. if pos == -1:
  28. return ''
  29.  
  30. return word[pos + 1:]
  31.  
  32.  
  33. def get_word(word):
  34. pos = word.find(':')
  35. if pos == -1:
  36. return ''
  37.  
  38. return word[:pos]
  39.  
  40.  
  41. def get_diapason(sentence, request, pos):
  42. """
  43. Возвращает найденный запрос в тексте "как в тексте".
  44. """
  45. temp = sentence[pos:pos + request.__len__()]
  46. result = list()
  47. for i in range(temp.__len__()):
  48. if request[i][0] == '*':
  49. if get_lemma(request[i]) == get_lemma(temp[i]):
  50. result = list()
  51. break
  52. result.append(get_word(temp[i]))
  53.  
  54. return result
  55.  
  56.  
  57. def check_lemma(sentence, request, pos):
  58. """
  59. Проверка на соответствие запроса и найденного совпадения.
  60. т.е. в словарь "маска" добавлять варианты из оригинала не нужно.
  61. Короче запутанно всё. Сложна.
  62. """
  63. temp = sentence[pos:pos + request.__len__()]
  64. sentence = list()
  65. for i in range(temp.__len__()):
  66. sentence.append(get_word(temp[i]))
  67.  
  68. result = False
  69. for i, word in enumerate(request):
  70. if get_word(word) != sentence[i]:
  71. result = True
  72. break
  73.  
  74. return result
  75.  
  76.  
  77. def normalize(request, lemma):
  78. """
  79. Приведение запроса к обычной форме.
  80. """
  81. result = list()
  82. for word in request:
  83. if lemma:
  84. if word[0] == '*':
  85. result.append('*')
  86. else:
  87. result.append(get_lemma(word))
  88. else:
  89. result.append(get_word(word))
  90.  
  91. return result
  92.  
  93.  
  94. def find_(text, request, detailed, mask, lemma=False):
  95. """
  96. Поиск запроса в тексте. С полным совпадением и похожие.
  97. """
  98. s_pos = 0
  99. while s_pos < text.__len__():
  100. sentence = text[s_pos]
  101. pos = 0
  102. for i in range(sentence.__len__()):
  103. # Установка слова по которому будем искать
  104. # и слова запроса.
  105. part = sentence[i]
  106. word = ''
  107. request_word = ''
  108. if lemma:
  109. word = get_lemma(part)
  110. request_word = get_lemma(request[pos])
  111. else:
  112. word = get_word(part)
  113. request_word = get_word(request[pos])
  114.  
  115. # Сравнение с текущим словом из request.
  116. if pos == request.__len__() - 1 and word == request_word:
  117. d_request = get_diapason(sentence, request, i - pos)
  118. # Для поиска по лемме не добавляем найденный запрос
  119. # если он символ в символ совпадает с тем что в тексте.
  120. # Потому-что он уже был добавлен при поиске не по лемме.
  121. if lemma and check_lemma(sentence, request, i - pos):
  122. if d_request != list():
  123. m_request = ['[']
  124. m_request += normalize(request, True)
  125. m_request.append(']')
  126. inc_dict(mask, m_request)
  127. inc_dict(detailed, d_request)
  128. del text[s_pos][i - pos:i + 1]
  129. text[s_pos].insert(i - pos, '_')
  130. s_pos -= 1
  131. break
  132.  
  133. if not lemma:
  134. if d_request != list():
  135. inc_dict(mask, normalize(request, False))
  136. inc_dict(detailed, d_request)
  137. del text[s_pos][i - pos:i + 1]
  138. text[s_pos].insert(i - pos, '_')
  139. s_pos -= 1
  140. break
  141.  
  142. pos = 0
  143. elif word == request_word or request_word[0] == '*':
  144. pos += 1
  145. else:
  146. pos = 0
  147.  
  148. s_pos += 1
  149.  
  150. return text
  151.  
  152.  
  153. def find(text, request, detailed, mask):
  154. """
  155. Обертка вокруг поиска.
  156. """
  157. start_time = time.time()
  158. requests = gen_variants(request)
  159. print('Всего запросов: ' + str(requests.__len__()))
  160. print('Время генерации запросов: ' + str(time.time() - start_time) + 'c.')
  161.  
  162. start_time = time.time()
  163. text = split(text)
  164. for pos, i in enumerate(requests):
  165. text = find_(text, i, detailed, mask) # Поиск по прямому вхождению.
  166. text = find_(text, i, detailed, mask, True) # Поиск по канонической словоформе(лемме).
  167. print('Время поиска по запросам: ' + str(time.time() - start_time) + 'c.')
  168.  
  169.  
  170. def gen_variants(request):
  171. """
  172. Генерация вариантов запроса при помощи дллки на плюсах.
  173. """
  174. # Извлечение леммы и объединение ["слово"] => ["слово:лемма"].
  175. words = split(clean_text(request))[0]
  176. lemmas = lemmatize(request)
  177. request = list()
  178. for i, word in enumerate(words):
  179. request.append(word + ':' + lemmas[i])
  180.  
  181. # Генерация всех вариантов.
  182. out_request = rmaker.compute_variants(request)
  183. out_request += rmaker.compute_variants_mixed(request)
  184. #out_request += sorted(rmaker.compute_variants_star(request), key=len, reverse=True)
  185. out_request += rmaker.compute_variants_mixed_star(request)
  186.  
  187. out_request = sorted(out_request, key=len, reverse=True)
  188.  
  189. return out_request
  190.  
  191.  
  192. # Help methods:
  193.  
  194. def inc_dict(dictionary, key):
  195. """
  196. Если такого ключа ещё нет, то создаем со значением ,
  197. иначе инкрементируем.
  198. """
  199. key = list2text(key)
  200. if key in dictionary.keys():
  201. dictionary[key] += 1
  202. else:
  203. dictionary[key] = 1
  204.  
  205.  
  206. def clean_list(sentence):
  207. """
  208. Очистка списка слов от мусора.
  209. """
  210. result = list()
  211. for i in sentence:
  212. i = i.strip()
  213. if i and i not in '.,-=\"\'':
  214. result.append(i)
  215.  
  216. return result;
  217.  
  218.  
  219. def clean_text(text):
  220. """
  221. Подготовка текста.
  222. """
  223. #text = re.sub('(?<=[a-zA-Zа-яА-Я]),', ', ', text)
  224. #text = re.sub('(?<=[0-9]).(<=[0-9])', '', text)
  225. #text = re.sub('(?<=[a-zA-Zа-яА-Я0-9])\/', ' / ', text)
  226. #text = re.sub('\+', '+ ', text)
  227. text = re.sub('((?<=[0-9])[\.,](?=[0-9]))', '_', text)
  228. text = re.sub('[\t]+', ' ', text)
  229. text = re.sub(' ', ' ', text)
  230. text = re.sub('[?!,;\-–\{\}\[\]\(\)«»″\\\/]+', '.', text)
  231. return re.sub('[*=#]', '', text).lower()
  232.  
  233.  
  234. def split(text, text_split_pattern = '[.]', text_only = False):
  235. """
  236. Разбивает текст на слова и предложения.
  237. """
  238. result = list()
  239. sentences = re.split(text_split_pattern, text.lower())
  240. if text_only:
  241. return clean_list(sentences)
  242.  
  243. for sentence in sentences:
  244. if sentence != '':
  245. sentence = sentence.split()
  246. for word in sentence:
  247. word.strip(', ')
  248.  
  249. if sentence != []:
  250. result.append(clean_list(sentence))
  251.  
  252. return result
  253.  
  254.  
  255. def list2text(sentence):
  256. """
  257. Объединение всех слов в списке, в предложение.
  258. """
  259. result = ''
  260. for word in sentence:
  261. result += word + ' '
  262.  
  263. return result.rstrip()
  264.  
  265.  
  266. def get_file_list(dir):
  267. """
  268. Возвращает список из всех файлов .txt в текущей директории.
  269. """
  270. result = list()
  271. for f in os.listdir(dir):
  272. if isfile(join(dir, f)) and f.rfind('.') != -1:
  273. if f[f.rfind('.') + 1:] == 'lem':
  274. result.append(dir + '\\' + f)
  275.  
  276. return result
  277.  
  278.  
  279. def make_csv(file_name, simple_data, lemma_data, words_count, char_count):
  280. """
  281. Создание csv файла из словаря(dict).
  282. """
  283. result = 'Ключевые слова(подробно),\n'
  284. result += 'ключ,к-во раз\n'
  285. for i in range(simple_data.__len__()):
  286. result += list(simple_data.keys())[i] + ',' + str(list(simple_data.values())[i]) + '\n'
  287.  
  288. common = 0
  289. for i in list(simple_data.values()):
  290. common += i
  291.  
  292. result += 'ИТОГО,' + str(common) + '\n'
  293. result += 'Объем текста слов,' + str(words_count) + '\n'
  294. result += 'Объем текста символов,' + str(char_count) + '\n'
  295. result += 'Ключевые слова(маска),\n'
  296. result += 'ключ,к-во раз\n'
  297. for i in range(lemma_data.__len__()):
  298. result += list(lemma_data.keys())[i] + ',' + str(list(lemma_data.values())[i]) + '\n'
  299.  
  300. common = 0
  301. for i in list(lemma_data.values()):
  302. common += i
  303.  
  304. result += 'ИТОГО,' + str(common) + '\n'
  305.  
  306. # Сохранение в файл.
  307. print('Сохранение файла \"' + file_name + '\".')
  308. f = open(file_name, 'w')
  309. f.write(result)
  310. f.close()
  311. print('Файл успешно сохранен.')
  312.  
  313.  
  314. if __name__ == '__main__':
  315. #split_test()
  316. #list2text_test()
  317. #clean_list_test()
  318. #lemmatize_test()
  319. #find_test()
  320.  
  321. request = ''
  322. while True:
  323. # Получение запроса.
  324. request = input('Запрос для поиска: ')
  325. #request = 'вывоз мусора контейнер 8 м3 балашиха'
  326. request = request.strip()
  327. if request == '' or request in 'exit quit close выйти закрыть':
  328. break
  329.  
  330. # Извлечение списка файлов.
  331. current_dir = os.path.dirname(os.path.abspath(__file__))
  332. file_list = get_file_list(current_dir)
  333.  
  334. # Поиск по всем файлам.
  335. print('Всего файлов: ' + str(file_list.__len__()))
  336. for i, file in enumerate(file_list):
  337. print('Поиск в файле: ' + str(i))
  338. simple_result = dict()
  339. lemma_result = dict()
  340. f = open(file, 'r')
  341. text = f.read()
  342. f.close()
  343. text = clean_text(text)
  344.  
  345. # Поиск.
  346. find(text, request, simple_result, lemma_result)
  347.  
  348. # Подготовка результата.
  349. splited = split(text)
  350. words_count = 0
  351. for sentence in splited:
  352. words_count += sentence.__len__()
  353.  
  354. make_csv(file + '.csv', simple_result,
  355. lemma_result, words_count, int(text.__len__() / 2))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement