Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import re
- from pymystem3 import Mystem
- import time
- import os
- import csv
- import functools
- from os.path import isfile, join
- from pymystem3 import Mystem
- import sys
- sys.path.append("./")
- import rmaker
- def lemmatize(text):
- """
- Приведение к нормальной форме.
- """
- m = Mystem()
- temp_res = m.lemmatize(text)
- return clean_list(temp_res)
- def get_lemma(word):
- pos = word.find(':')
- if pos == -1:
- return ''
- return word[pos + 1:]
- def get_word(word):
- pos = word.find(':')
- if pos == -1:
- return ''
- return word[:pos]
- def get_diapason(sentence, request, pos):
- """
- Возвращает найденный запрос в тексте "как в тексте".
- """
- temp = sentence[pos:pos + request.__len__()]
- result = list()
- for i in range(temp.__len__()):
- if request[i][0] == '*':
- if get_lemma(request[i]) == get_lemma(temp[i]):
- result = list()
- break
- result.append(get_word(temp[i]))
- return result
- def check_lemma(sentence, request, pos):
- """
- Проверка на соответствие запроса и найденного совпадения.
- т.е. в словарь "маска" добавлять варианты из оригинала не нужно.
- Короче запутанно всё. Сложна.
- """
- temp = sentence[pos:pos + request.__len__()]
- sentence = list()
- for i in range(temp.__len__()):
- sentence.append(get_word(temp[i]))
- result = False
- for i, word in enumerate(request):
- if get_word(word) != sentence[i]:
- result = True
- break
- return result
- def normalize(request, lemma):
- """
- Приведение запроса к обычной форме.
- """
- result = list()
- for word in request:
- if lemma:
- if word[0] == '*':
- result.append('*')
- else:
- result.append(get_lemma(word))
- else:
- result.append(get_word(word))
- return result
- def find_(text, request, detailed, mask, lemma=False):
- """
- Поиск запроса в тексте. С полным совпадением и похожие.
- """
- s_pos = 0
- while s_pos < text.__len__():
- sentence = text[s_pos]
- pos = 0
- for i in range(sentence.__len__()):
- # Установка слова по которому будем искать
- # и слова запроса.
- part = sentence[i]
- word = ''
- request_word = ''
- if lemma:
- word = get_lemma(part)
- request_word = get_lemma(request[pos])
- else:
- word = get_word(part)
- request_word = get_word(request[pos])
- # Сравнение с текущим словом из request.
- if pos == request.__len__() - 1 and word == request_word:
- d_request = get_diapason(sentence, request, i - pos)
- # Для поиска по лемме не добавляем найденный запрос
- # если он символ в символ совпадает с тем что в тексте.
- # Потому-что он уже был добавлен при поиске не по лемме.
- if lemma and check_lemma(sentence, request, i - pos):
- if d_request != list():
- m_request = ['[']
- m_request += normalize(request, True)
- m_request.append(']')
- inc_dict(mask, m_request)
- inc_dict(detailed, d_request)
- del text[s_pos][i - pos:i + 1]
- text[s_pos].insert(i - pos, '_')
- s_pos -= 1
- break
- if not lemma:
- if d_request != list():
- inc_dict(mask, normalize(request, False))
- inc_dict(detailed, d_request)
- del text[s_pos][i - pos:i + 1]
- text[s_pos].insert(i - pos, '_')
- s_pos -= 1
- break
- pos = 0
- elif word == request_word or request_word[0] == '*':
- pos += 1
- else:
- pos = 0
- s_pos += 1
- return text
- def find(text, request, detailed, mask):
- """
- Обертка вокруг поиска.
- """
- start_time = time.time()
- requests = gen_variants(request)
- print('Всего запросов: ' + str(requests.__len__()))
- print('Время генерации запросов: ' + str(time.time() - start_time) + 'c.')
- start_time = time.time()
- text = split(text)
- for pos, i in enumerate(requests):
- text = find_(text, i, detailed, mask) # Поиск по прямому вхождению.
- text = find_(text, i, detailed, mask, True) # Поиск по канонической словоформе(лемме).
- print('Время поиска по запросам: ' + str(time.time() - start_time) + 'c.')
- def gen_variants(request):
- """
- Генерация вариантов запроса при помощи дллки на плюсах.
- """
- # Извлечение леммы и объединение ["слово"] => ["слово:лемма"].
- words = split(clean_text(request))[0]
- lemmas = lemmatize(request)
- request = list()
- for i, word in enumerate(words):
- request.append(word + ':' + lemmas[i])
- # Генерация всех вариантов.
- out_request = rmaker.compute_variants(request)
- out_request += rmaker.compute_variants_mixed(request)
- #out_request += sorted(rmaker.compute_variants_star(request), key=len, reverse=True)
- out_request += rmaker.compute_variants_mixed_star(request)
- out_request = sorted(out_request, key=len, reverse=True)
- return out_request
- # Help methods:
- def inc_dict(dictionary, key):
- """
- Если такого ключа ещё нет, то создаем со значением ,
- иначе инкрементируем.
- """
- key = list2text(key)
- if key in dictionary.keys():
- dictionary[key] += 1
- else:
- dictionary[key] = 1
- def clean_list(sentence):
- """
- Очистка списка слов от мусора.
- """
- result = list()
- for i in sentence:
- i = i.strip()
- if i and i not in '.,-=\"\'':
- result.append(i)
- return result;
- def clean_text(text):
- """
- Подготовка текста.
- """
- #text = re.sub('(?<=[a-zA-Zа-яА-Я]),', ', ', text)
- #text = re.sub('(?<=[0-9]).(<=[0-9])', '', text)
- #text = re.sub('(?<=[a-zA-Zа-яА-Я0-9])\/', ' / ', text)
- #text = re.sub('\+', '+ ', text)
- text = re.sub('((?<=[0-9])[\.,](?=[0-9]))', '_', text)
- text = re.sub('[\t]+', ' ', text)
- text = re.sub(' ', ' ', text)
- text = re.sub('[?!,;\-–\{\}\[\]\(\)«»″\\\/]+', '.', text)
- return re.sub('[*=#]', '', text).lower()
- def split(text, text_split_pattern = '[.]', text_only = False):
- """
- Разбивает текст на слова и предложения.
- """
- result = list()
- sentences = re.split(text_split_pattern, text.lower())
- if text_only:
- return clean_list(sentences)
- for sentence in sentences:
- if sentence != '':
- sentence = sentence.split()
- for word in sentence:
- word.strip(', ')
- if sentence != []:
- result.append(clean_list(sentence))
- return result
- def list2text(sentence):
- """
- Объединение всех слов в списке, в предложение.
- """
- result = ''
- for word in sentence:
- result += word + ' '
- return result.rstrip()
- def get_file_list(dir):
- """
- Возвращает список из всех файлов .txt в текущей директории.
- """
- result = list()
- for f in os.listdir(dir):
- if isfile(join(dir, f)) and f.rfind('.') != -1:
- if f[f.rfind('.') + 1:] == 'lem':
- result.append(dir + '\\' + f)
- return result
- def make_csv(file_name, simple_data, lemma_data, words_count, char_count):
- """
- Создание csv файла из словаря(dict).
- """
- result = 'Ключевые слова(подробно),\n'
- result += 'ключ,к-во раз\n'
- for i in range(simple_data.__len__()):
- result += list(simple_data.keys())[i] + ',' + str(list(simple_data.values())[i]) + '\n'
- common = 0
- for i in list(simple_data.values()):
- common += i
- result += 'ИТОГО,' + str(common) + '\n'
- result += 'Объем текста слов,' + str(words_count) + '\n'
- result += 'Объем текста символов,' + str(char_count) + '\n'
- result += 'Ключевые слова(маска),\n'
- result += 'ключ,к-во раз\n'
- for i in range(lemma_data.__len__()):
- result += list(lemma_data.keys())[i] + ',' + str(list(lemma_data.values())[i]) + '\n'
- common = 0
- for i in list(lemma_data.values()):
- common += i
- result += 'ИТОГО,' + str(common) + '\n'
- # Сохранение в файл.
- print('Сохранение файла \"' + file_name + '\".')
- f = open(file_name, 'w')
- f.write(result)
- f.close()
- print('Файл успешно сохранен.')
- if __name__ == '__main__':
- #split_test()
- #list2text_test()
- #clean_list_test()
- #lemmatize_test()
- #find_test()
- request = ''
- while True:
- # Получение запроса.
- request = input('Запрос для поиска: ')
- #request = 'вывоз мусора контейнер 8 м3 балашиха'
- request = request.strip()
- if request == '' or request in 'exit quit close выйти закрыть':
- break
- # Извлечение списка файлов.
- current_dir = os.path.dirname(os.path.abspath(__file__))
- file_list = get_file_list(current_dir)
- # Поиск по всем файлам.
- print('Всего файлов: ' + str(file_list.__len__()))
- for i, file in enumerate(file_list):
- print('Поиск в файле: ' + str(i))
- simple_result = dict()
- lemma_result = dict()
- f = open(file, 'r')
- text = f.read()
- f.close()
- text = clean_text(text)
- # Поиск.
- find(text, request, simple_result, lemma_result)
- # Подготовка результата.
- splited = split(text)
- words_count = 0
- for sentence in splited:
- words_count += sentence.__len__()
- make_csv(file + '.csv', simple_result,
- lemma_result, words_count, int(text.__len__() / 2))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement