def test_constant_attribute(): MONEY_RULE = rule( gram('INT').interpretation(Money.count), dictionary({'тысяча'}).interpretation(Money.base.const(10**3)), dictionary({'рубль', 'доллар'}).interpretation(Money.currency), ).interpretation(Money) parser = Parser(MONEY_RULE) matches = list(parser.match('1 тысяча рублей')) assert matches[0].fact == Money(count=1, base=1000, currency='рублей')
def yargy_smart_home(msg): Do = fact('Entity', ['action', 'object', 'place']) Actions = dictionary({'Включи', 'Отключи', 'Выключи'}) Objects = dictionary( {'Лампочку', 'Свет', 'Розетку', 'Видеокамеру', 'Камеру'}) ObjectsList = or_( rule(Objects), rule(Objects, Objects), ) Prep = dictionary({'в', 'на'}) Place = dictionary({ 'Гостевой', 'Ванной', 'спальной', 'спальне', 'холле', 'коридоре', 'кухне' }) Room = {'комната'} ActionPhrase = or_( rule(Actions.interpretation(Do.action.normalized()), Objects.interpretation(Do.object.normalized()), Prep.optional(), Place.interpretation(Do.place.normalized()), rule(normalized('комната')).optional()), rule(Actions.interpretation(Do.action.normalized()), Objects.interpretation(Do.object.normalized()), Prep.optional(), Place.interpretation(Do.place.normalized())), rule(Prep.optional(), Place.interpretation(Do.place.normalized()), rule(normalized('комната')).optional(), Actions.interpretation(Do.action.normalized()), Objects.interpretation( Do.object.normalized()))).interpretation(Do) res = [] parser = Parser(ActionPhrase) for match in parser.findall(msg): res.append({ 'Действие': match.fact.action, 'Объект': match.fact.object, 'Место': match.fact.place, }) return res
def __init__(self, name=None): self.section_rule = rule( dictionary({"раздел", "тема", "дисциплина", "наименование"})) self.lectures_rule = rule( morph_pipeline([ 'тема лекций', 'содержание занятий', 'содержание лекционного занятия' ])) self.pract_rule = rule(morph_pipeline(['наименование'])) self.srs_rule = rule(morph_pipeline(['СРС'])) self.docxdoc = DocumentPrepare(name).open_doc()
def yargy_get_genre(msg): Genre = fact('Genre', ['genre']) GENRES = { 'ужасы', 'ужастики', 'мелодрама', 'комедия', 'боевик', 'триллер', 'мультик', 'мультфильм', 'драма' } GENRES_NAME = dictionary(GENRES) GENRES_WORDS = or_(rule(normalized('жанр')), rule(normalized('раздел'))) GENRE_PHRASE = or_(rule(GENRES_NAME, GENRES_WORDS.optional()), rule(GENRES_WORDS.optional(), GENRES_NAME)).interpretation( Genre.genre.inflected()).interpretation(Genre) res = [] parser = Parser(GENRE_PHRASE) for match in parser.findall(msg): res.append(match.fact.genre) return res
def yargy_get_channel(msg): Channel = fact('Channel', ['name']) CNANNELS = { 'Первый', 'Россия', 'ТВЦ', 'НТВ', 'ТНТ', 'СТС', 'Культура', 'Дождь', 'Спас' } CNANNELS_NAME = dictionary(CNANNELS) CHANNEL_WORDS = or_(rule(normalized('канал')), rule(normalized('программа'))) CHANNEL_PHRASE = or_( rule(CHANNEL_WORDS, CNANNELS_NAME), rule(CNANNELS_NAME, CHANNEL_WORDS.optional())).interpretation( Channel.name.inflected()).interpretation(Channel) res = [] parser = Parser(CHANNEL_PHRASE) for match in parser.findall(msg): # print(match.fact) for channel in CNANNELS: if channel.lower() in match.fact.name: res.append(channel) return res
"час": TemporalUnit.HOUR, "день": TemporalUnit.DAY, "неделя": TemporalUnit.WEEK, "месяц": TemporalUnit.MONTH, "год": TemporalUnit.YEAR, } WORDS_NAMED_INTERVAL = { "полчаса": NamedInterval.HALF_AN_HOUR, } # Parts # TODO FIX: find adequate way to parse numbers GENERIC_NUMBER = or_( dictionary(WORDS_HOUR_OF_A_DAY), and_(gte(0), lte(1_000_000_000)) # gram('NUMR'), # # https://github.com/OpenCorpora/opencorpora/issues/818 # dictionary({ # 'ноль', # 'один' # }), ) def normalize_generic_number(val) -> int: return int(WORDS_HOUR_OF_A_DAY.get(val, val)) RELATIVE_DAY = dictionary(WORDS_RELATIVE_DAY)
Position = fact('position', ['level', 'field', 'name']) LEVEL = rule( caseless_pipeline([ 'junior', 'middle', 'senior', 'lead', 'chief', 'head', 'team lead', "старший", "младший", "руководитель направления" ]).interpretation(Position.level)) # TODO: нужно учесть жаргонные варианты (датасаентолог, датасатанист и т.д.) Скорее всего, придется парсить регулярками NAME = rule( or_( caseless_pipeline([ 'data scientist', 'data engineer', 'engineer', 'analyst', 'data analyst', 'data manager', 'scientist', 'researcher', "developer", "intern" ]), rule(dictionary(['DS', 'DE']), is_capitalized()), morph_pipeline(["аналитик", "разработчик", "стажер"])).interpretation(Position.name.inflected())) FIELD = rule( caseless_pipeline([ 'ML', 'DL', 'CV', 'computer vision', 'NLP', 'bi', 'machine learning', 'deep learning', 'software', 'research', 'big data', 'python', 'c++', "scala", "java", 'ios', "android", 'devops', "backend", 'frontend' ]).interpretation(Position.field)) HEAD = rule( caseless('head').interpretation(Position.level), eq('of'), caseless_pipeline(['analytics', 'predictive analytics', 'data science']).interpretation(Position.field))
'февраль': 2, 'март': 3, 'апрель': 4, 'май': 5, 'июнь': 6, 'июль': 7, 'август': 8, 'сентябрь': 9, 'октябрь': 10, 'ноябрь': 11, 'декабрь': 12, } MONTH_NAME = dictionary(MONTHS).interpretation( Date.month.normalized().custom(MONTHS.__getitem__) ) MONTH = and_( gte(1), lte(12) ).interpretation( Date.month.custom(int) ) DAY = and_( gte(1), lte(31) ).interpretation( Date.day.custom(int) )
from ipymarkup import show_markup from yargy import rule, and_, or_ from yargy.interpretation import fact, attribute from yargy.predicates import dictionary, normalized ProfileTypeFact = fact('ProfileTypeFact', ['profile']) PROFILES = { 'модель': 'Model', 'визажист': 'Visagiste', 'фотограф': 'Photographer', 'стилист': 'Stylist', } NAME = dictionary(PROFILES).interpretation( ProfileTypeFact.profile.normalized().custom(PROFILES.__getitem__)) PROFILE_TYPE_PARSER = or_(rule(NAME), ).interpretation(ProfileTypeFact)
class AddrPart(AddrPart): @property def obj(self): from natasha import obj part = self.value return obj.AddrPart(part.value, part.type) INT = type('INT') LETTER = in_caseless(set('абвгдежзиклмнопрстуфхшщэюя')) TYPE_CITY = dictionary({'город'}).interpretation(City.typeCity) STRUCTURE_TYPE = dictionary({'строение', 'ст'}).interpretation(Structure.structureType) TYPE_APPART = dictionary({'квартира'}).interpretation(Appart.typeAppart) BUILDING_TYPE = dictionary({'дом', 'шоссе', 'проспект', 'улица'}).interpretation(Building.buildingType) VALUE = rule(INT, LETTER.optional()) SEP = in_(r'/\-') BUILDING_VALUE = or_(rule(VALUE, LETTER), rule(VALUE)).interpretation(Building.buildingName)
NAME = SIMPLE_NAME.transform(StripInterpretationTransformator) PERSON = POSITION_NAME.transform(StripInterpretationTransformator) ### NATASHA EXTRACTOR DEF from natasha.extractors import Extractor class eduorgExtractor(Extractor): def __init__(self): super(eduorgExtractor, self).__init__(EDUORG) ### import re from lib.func import get_dictPath, load_regex EDUORG_DICT = dictionary( set(load_dict(get_dictPath('eduorg', 'dict_main.txt')))) EDUORG_DICT_REGEXP = re.compile( load_regex(get_dictPath('eduorg', 'dict_main.txt'))) ## 1 - FACT INIT eduorg = fact('eduorg', ['name']) ### ### 2 - INIT GRAMS & GRAM RULES (pymorphy2) ADJF = gram('ADJF') NOUN = gram('NOUN') INT = gram('INT') TITLE = is_title() PRE_WORDS = rule( or_(
Mosmetro.name)).interpretation(Mosmetro) Location = fact( 'Location', [ 'name', 'region_or_island', 'ao_or_fo', 'federation', 'adjx_federation', 'state', 'locality', 'sea', 'island' ], ) gnc = gnc_relation() LOCALITY = rule( and_( dictionary({ 'город', # 'деревня', # 'село', }), not_(or_( gram('Abbr'), gram('PREP'), gram('CONJ'), gram('PRCL'), ), ), ).optional(), and_(gram('ADJF'), ).match(gnc).optional(), and_( gram('Geox'), is_capitalized(), not_(or_( gram('Abbr'),
['week', attribute('current_era', True)]) WEEKS = { 'Понедельник': 1, 'Вторник': 2, 'Среда': 3, 'Четверг': 4, 'Пятница': 5, 'Суббота': 6, 'Воскресенье': 7, 'Пнд': 1, 'Втр': 2, 'Срд': 3, 'Чтв': 4, 'Птн': 5, 'Сбт': 6, 'Вск': 7, 'Пн': 1, 'Вт': 2, 'Ср': 3, 'Чт': 4, 'Пт': 5, 'Сб': 6, 'Вс': 7, } WEEK_NAME = dictionary(WEEKS).interpretation( DayWeekDateFact.week.normalized().custom(WEEKS.__getitem__)) WEEK_DATE_PARSER = or_(rule(WEEK_NAME)).interpretation(DayWeekDateFact)
Money.multiplier ) ######## # # NUMERAL # ####### NUMR = or_( gram('NUMR'), # https://github.com/OpenCorpora/opencorpora/issues/818 dictionary({ 'ноль', 'один' }), ) MODIFIER = in_caseless({ 'целых', 'сотых', 'десятых' }) PART = or_( rule( or_( INT, NUMR, MODIFIER
MONTHS = { 'январь': 1, 'февраль': 2, 'март': 3, 'апрель': 4, 'май': 5, 'июнь': 6, 'июль': 7, 'август': 8, 'сентябрь': 9, 'октябрь': 10, 'ноябрь': 11, 'декабрь': 12, } MONTH_NAME = dictionary(MONTHS).interpretation(Date.month.normalized()) MONTH = and_(gte(1), lte(12)).interpretation(Date.month) DAY = and_(gte(1), lte(31)).interpretation(Date.day) YEAR_WORD = or_(rule('г', eq('.').optional()), rule(normalized('год'))) YEAR = and_(gte(1900), lte(2100)).interpretation(Date.year) YEAR_SHORT = and_(gte(0), lte(99)).interpretation(Date.year) DATE = or_( rule(DAY, '.', MONTH, '.', or_(YEAR, YEAR_SHORT), YEAR_WORD.optional()), rule(YEAR, YEAR_WORD), rule(DAY, MONTH_NAME),
Nums = fact('Nums', [attribute('values').repeatable()]) __literals = { 'один': 1, 'два': 2, 'три': 3, 'четыре': 4, 'пять': 5, 'шесть': 6, 'семь': 7, 'восемь': 8, 'девять': 9, } LITERAL = dictionary(__literals).means( interp.normalized().custom(__literals.get)) CONJ_NUMS = in_caseless('-и,') NUMERAL = or_(*[eq(str(i)) for i in __literals.values()]).means(interp.custom(int)) # вестибюль 1 и 2 LIST_OF_NUMERALS = connect(NUMERAL.means(Nums.values), CONJ_NUMS) \ .means(Nums).means(meaning.custom(lambda p: list(sorted(set(p.values))))) # первый и второй вестибюли LIST_OF_LITERALS = connect(LITERAL.means(Nums.values), CONJ_NUMS) \ .means(Nums).means(meaning.custom(lambda p: list(sorted(set(p.values)))))
Location = fact( 'Location', ['name'], ) gnc = gnc_relation() REGION = rule( gram('ADJF').match(gnc), dictionary({ 'край', 'район', 'область', 'губерния', 'уезд', }).match(gnc), ).interpretation(Location.name.inflected()) gnc = gnc_relation() FEDERAL_DISTRICT = rule( rule(caseless('северо'), '-').optional(), dictionary({ 'центральный', 'западный', 'южный', 'кавказский', 'приволжский',
THOUSAND = or_(rule(caseless('т'), DOT), rule(caseless('тыс'), DOT.optional()), rule(normalized('тысяча'))).interpretation(const(10**3)) MULTIPLIER = or_(MILLIARD, MILLION, THOUSAND).interpretation(Money.multiplier) ######## # # NUMERAL # ####### NUMR = or_( gram('NUMR'), # https://github.com/OpenCorpora/opencorpora/issues/818 dictionary({'ноль', 'один'}), ) MODIFIER = in_caseless({'целых', 'сотых', 'десятых'}) PART = or_(rule(or_(INT, NUMR, MODIFIER)), MILLIARD, MILLION, THOUSAND, CURRENCY, COINS_CURRENCY) BOUND = in_('()//') NUMERAL = rule(BOUND, PART.repeatable(), BOUND) ####### # # AMOUNT #
'я', 'й', 'е', 'ое', 'ая', 'ий', 'ой' }) ) ######### # # STRANA # ########## # TODO COUNTRY_VALUE = dictionary({ 'россия', 'украина' }) ABBR_COUNTRY_VALUE = in_caseless({ 'рф' }) COUNTRY = or_( COUNTRY_VALUE, ABBR_COUNTRY_VALUE ).interpretation( Country.name ).interpretation( Country )
THOUSAND = or_(rule(caseless('т'), DOT), rule(caseless('к')), rule(caseless('k')), rule(caseless('тыс'), DOT.optional()), rule(normalized('тысяча'))).interpretation(const(10**3)) MULTIPLIER = or_(MILLIARD, MILLION, THOUSAND).interpretation(Money.multiplier) ######## # # NUMERAL # ####### NUMR = or_( gram('NUMR'), # https://github.com/OpenCorpora/opencorpora/issues/818 dictionary({'ноль', 'один'}), ) # TODO: можно выпилить дробные части для снижения числа ложных срабатываний, их все равно не бывает в реальных вилках # Хотя одна вакаха в Tampere University of Technology реально была с дробями MODIFIER = in_caseless({'целых', 'сотых', 'десятых'}) PART = or_(rule(or_(INT, NUMR, MODIFIER)), MILLIARD, MILLION, THOUSAND, CURRENCY, COINS_CURRENCY) # TODO: вот здесь можно поправить, чтобы телефоны не парсились BOUND = in_('()//') NUMERAL = rule(BOUND, PART.repeatable(), BOUND) ####### # # AMOUNT
# coding: utf-8 from __future__ import unicode_literals from natasha.data import load_lines from yargy.predicates import (dictionary) DATERELATIVE_DICT = dictionary(set(load_lines('./../dictionaries/null.txt')))
'д', 'день', 'сутки', 'смена', 'm', 'month', 'м' 'месяц', 'мес', 'y', 'year', 'г', 'год', } PERIOD = dictionary(PERIODS) PER = or_(eq('/'), in_caseless({'в', 'за', 'per'})) RATE = rule(PER, PERIOD.interpretation(Money.period)) MONEY = rule( or_( in_({ '•', ':', '`', '~', '*', '-', '–', '—', ';', '.', '(', 'от', 'from' }), type('RU'), type('LATIN'), ).optional(), CURRENCY.interpretation(Money.currency).optional(), eq('+').optional(),
def __init__(self, filename, university): self.filename = filename self.university = university self.rpd_task_and_goals = morph_pipeline([ 'цели и задачи', 'цели освоения', 'задачи освоения', 'аннотация', 'краткое содержание', 'краткое описание' ]) self.rpd_education_result = morph_pipeline( ['планируемый результат обучение', 'компетенции']) self.rpd_discipline_link = morph_pipeline( ['место учебный дисциплина', 'место дисциплины']) self.rpd_discipline_structure = caseless_pipeline( ['содержание дисциплины', 'структура дисциплины']) self.rpd_lecture_theme = morph_pipeline(['лекции']) self.rpd_practice_theme = morph_pipeline([ 'практические занятия', 'семинар', 'семинарские занятия', 'лабораторные работы' ]) self.rpd_selfwork_theme = morph_pipeline([ 'самостоятельная работа обучающихся по дисциплине', 'самостоятельная работа студентов', 'домашняя работа' ]) self.rpd_education_zyn = rule(dictionary({'Знать', 'Уметь', 'Владеть'})) self.section_rule = rule( dictionary({"раздел", "тема", "дисциплина", "наименование"})) self.prd_lectures = rule( morph_pipeline([ 'тема лекций', 'содержание занятий', 'содержание лекционного занятия' ])) self.prd_practices = rule( morph_pipeline( ['наименование', 'содержание практического занятия', 'тема'])) self.rpd_srs = rule( morph_pipeline([ 'СРС', 'содержание занятий', 'содержание задания', 'тема СРО', 'тема СРС' ])) self.rpd_name = rule( morph_pipeline([ 'рабочая программа дисциплины', 'дисциплина', 'программа дисциплины' ])) self.table_rpd_name = rule(dictionary({'дисциплина'})) self.rpd_lectures_optional = rule(morph_pipeline(['содержание'])) self.rpd_practices_optional = rule( morph_pipeline(['содержание', 'cодержание практического занятия'])) self.rpd_srs_optional = rule( morph_pipeline(['содержание', 'содержание задания'])) self.documentText = dict() self.docs_headers = list() self.fullText = list() parser_RPD_task_and_goals = Parser(self.rpd_task_and_goals) parser_RPD_education_result = Parser(self.rpd_education_result) parser_RPD_discipline_link = Parser(self.rpd_discipline_link) parser_PRD_discipline_structure = Parser(self.rpd_discipline_structure) parser_PRD_lecture_theme = Parser(self.rpd_lecture_theme) parser_RPD_practice_theme = Parser(self.rpd_practice_theme) parser_RPD_selfwork_theme = Parser(self.rpd_selfwork_theme) parser_PRD_zyn_result = Parser(self.rpd_education_zyn) parser_PRD_themes = Parser(self.section_rule) parser_PRD_lectures = Parser(self.prd_lectures) parser_PRD_practices = Parser(self.prd_practices) parser_RPD_srs = Parser(self.rpd_srs) parser_RPD_name = Parser(self.rpd_name) self.parser_table_RPD_name = Parser(self.table_rpd_name) parser_RPD_lectures_desc = Parser(self.rpd_lectures_optional) parser_RPD_practices_desc = Parser(self.rpd_practices_optional) parser_RPD_srs_desc = Parser(self.rpd_srs_optional) self.get_rpd_text(filename) self.documentText['университет'] = self.university self.documentText['название дисциплины'] = self.get_rpd_name( parser_RPD_name) self.documentText[ 'направление подготовки'] = self.get_direction_of_preparation() self.documentText['цели и задачи'] = "".join( self.find_boundries(parser_RPD_task_and_goals)) self.documentText['результаты обучения'] = self.find_boundries( parser_RPD_education_result) fgos_table = "" flag = True if self.documentText['результаты обучения'] is not None: for item in self.documentText['результаты обучения']: if "Таблица: " in item: fgos_table = item[8:] self.documentText['результаты обучения'] = item if fgos_table == "": fgos_table = self.documentText['результаты обучения'] flag = False self.documentText['ЗУН'] = self.get_zyn_results( fgos_table, parser_PRD_zyn_result, flag) temp = "" for key, value in self.documentText['ЗУН'].items(): temp += key + " " for item in value: temp += "".join(item) + " " self.documentText['ЗУН'] = temp.replace("~", "") self.documentText['компетенции'] = self.search_place_fgos( "".join(fgos_table)) temp = "" for key, value in self.documentText['компетенции'].items(): temp += key + " " + value self.documentText['компетенции'] = temp self.documentText['результаты обучения'] = "".join( self.documentText['результаты обучения']).replace("~", '\t').replace( "@", '\n') self.documentText['связь дисциплины'] = "".join( self.find_boundries(parser_RPD_discipline_link)).replace( "Таблица: ", "").replace("~", "\t").replace("@", "\n") self.documentText['структура дисциплины'] = self.find_boundries( parser_PRD_discipline_structure) discipline_themes_table = "" for item in self.documentText['структура дисциплины']: if "Таблица: " in item: discipline_themes_table = item break self.documentText['структура дисциплины'] = "".join( self.documentText['структура дисциплины']).replace( "Таблица: ", '').replace("~", '\t').replace("@", "\n") self.documentText['темы структуры дисципилны'] = "".join( self.convert_string_to_table(discipline_themes_table[8:], parser_PRD_themes)) self.documentText['лекции'] = self.find_boundries( parser_PRD_lecture_theme) if self.documentText['лекции'] is not None: discipline_lectures_table = "" for item in self.documentText['лекции']: if "Таблица: " in item: discipline_lectures_table = item break self.documentText['темы лекций'] = "".join( self.convert_string_to_table(discipline_lectures_table[8:], parser_PRD_lectures)) self.documentText['описание лекций'] = "".join( self.convert_string_to_table(discipline_lectures_table[8:], parser_RPD_lectures_desc)) self.documentText['лекции'] = "".join( self.documentText['лекции']).replace("Таблица: ", '').replace( "~", '\t').replace("@", '\n') self.documentText['практики'] = self.find_boundries( parser_RPD_practice_theme) if self.documentText['практики'] is not None: discipline_practises_table = "" for item in self.documentText['практики']: if "Таблица: " in item: discipline_practises_table = item break self.documentText['темы практик'] = "".join( self.convert_string_to_table(discipline_practises_table[8:], parser_PRD_practices)) self.documentText['описание практик'] = "" # self.convert_string_to_table(discipline_lectures_table[8:],parser_RPD_practices_desc) self.documentText['практики'] = "".join( self.documentText['практики']).replace( "Таблица: ", '').replace("~", '\t').replace("@", '\n') self.documentText['СРС'] = self.find_boundries( parser_RPD_selfwork_theme) if self.documentText['СРС'] is not None: discipline_srs_table = "" for item in self.documentText['СРС']: if "Таблица: " in item: discipline_srs_table = item break self.documentText['темы СРС'] = "".join( self.convert_string_to_table(discipline_srs_table[8:], parser_RPD_srs)) self.documentText['описание СРС'] = "" # self.convert_string_to_table(discipline_srs_table[8:], parser_RPD_srs_desc) self.documentText['СРС'] = "".join( self.documentText['СРС']).replace("Таблица: ", '').replace( "~", '\t').replace("@", '\n')
'1.3. Планируемые результаты обучения по дисциплине ', 'Перечень планируемых результатов обучения, соотнесенных с планируемыми результатами освоения образовательной программы', '\nПеречень планируемых результатов обучения, соотнесенных с планируемыми результатами освоения образовательной программы', '1.3. Перечень планируемых результатов обучения, соотнесенных ' ] from yargy import Parser, rule, and_, or_ from yargy.predicates import gram, is_capitalized, dictionary, is_upper, length_eq, is_title from docx import Document from docx.shared import Inches import os, subprocess baseDir = r'C:\Users\Катя\Desktop\рпд' isResults = rule( and_(dictionary({'Знать', 'Уметь', 'Владеть'}), is_capitalized())) result_rule = Parser(isResults) IsCompetitionsAndResults = rule(dictionary({'результат'})) table_rule = Parser(IsCompetitionsAndResults) def GetDocuments(): documents = [] for filename in os.listdir(baseDir): if filename.endswith('.docx'): documents.append(filename) return documents def GetIndexPart(list_header_result):
documents = GetDocuments() path = baseDir + '\\' + documents[0] print(path) document = Document(path) from yargy import Parser, rule, and_ from yargy.predicates import gram, is_capitalized, dictionary Name = rule( and_( gram('ADJF'), or_(is_capitalized(), is_upper() ) # http://pymorphy2.readthedocs.io/en/latest/user/grammemes.html ), gram('ADJF').optional().repeatable(), dictionary({'институт', 'кафедра', 'университет'})) Name1 = rule( dictionary({'институт', 'кафедра', 'университет'}), gram('ADJF'), gram('ADJF').optional().repeatable(), gram('NOUN'), ) parser = Parser(Name) # parser = Parser(Name1) for table in document.tables: for row in table.rows: for cell in row.cells: for match in parser.findall(cell.text): print([_.value for _ in match.tokens])
from yargy.relations import gnc_relation Location = fact( 'Location', ['name'], ) gnc = gnc_relation() REGION = rule( gram('ADJF').match(gnc), dictionary({ 'край', 'район', 'область', 'губерния', 'уезд', }).match(gnc), ).interpretation(Location.name.inflected()) gnc1 = gnc_relation() gnc2 = gnc_relation() FEDERAL_DISTRICT = rule( rule(caseless('северо'), '-').optional(), dictionary({ 'центральный', 'западный', 'южный', 'кавказский',
from yargy import Parser, rule, and_, or_ from yargy.predicates import gram, is_capitalized, dictionary, in_, normalized, eq, caseless, type from yargy.interpretation import fact DOT = eq('.') POSITION = rule( or_(eq('врид'), eq('врио')).optional(), or_(rule('пом', DOT.optional()), rule('зам', DOT.optional()), rule('ст', DOT.optional()), rule(dictionary({'заместитель'}))).optional(), normalized('полковой').optional(), or_( rule('сотр', DOT.optional()), rule( dictionary({ 'оперуполномоченный', 'сотрудник', 'командир', 'уполномоченный', 'шофер', 'следователь', 'наркома', 'работник', 'инспектор', 'комендант', 'разведчик', 'начальник', 'секретарь', 'особоуполномоченный', 'председатель', 'фельдъегерь', 'сотрудница', 'лейтенант', 'референт', 'слушатель', 'руководитель', 'переводчик', 'управляющий' })), rule(caseless('нач'), DOT), rule(normalized('министра'), 'внутренних', 'дел')), or_(rule(eq('контрразведки')), rule(eq('особой'), eq('роты'))).optional()) pos_parser = Parser(POSITION) def parse(d): for match in pos_parser.findall(d):
# coding: utf-8 from __future__ import unicode_literals from natasha.data import load_lines from yargy.predicates import (dictionary) COUNTRY_DICT = dictionary(set(load_lines('./../dictionaries/null.txt')))
COMPLEX = or_( rule( and_(ADJF), NOUN ), rule( TITLE, DASH.optional(), TITLE ), ) EXCEPTION = dictionary({ 'арбат', 'варварка', 'мельникайте', 'каховка', 'зорге' }) MAYBE_NAME = or_( rule(SIMPLE), COMPLEX, rule(EXCEPTION) ) NAME = or_( MAYBE_NAME, LET, DATE, IMENI
def __init__(self): super(NerTimeCount, self).__init__() self.last_request = None self.last_result = [None, None, None] self.name = 'TimeCount' # переводим числа от 1 до 59 в текст n2t60 = [n2t(i) for i in range(1, 60)] # для поиска порядковых числительных def not_coll_numbers(x): return ('NUMR' in str(morph.parse(x)[0].tag) and ('Coll' not in str(morph.parse(x)[0].tag))) or x == 'один' # часы в словах hours_t = and_(dictionary(n2t60[:24] + ["полтора", "полдень"]), custom(not_coll_numbers)) # минуты в словах minutes_t = dictionary(n2t60) coll_numbers_dic = dictionary( ["двое", "трое", "четверо", "пятеро", "шестеро", "семеро"]) list_0n = {"00", "01", "02", "03", "04", "05", "06", "08", "09"} # часы в цифрах hours_n = or_(and_(gte(1), lte(23)), in_(list_0n)) # минуты в цифрах minutes_n = or_(and_(gte(1), lte(59)), in_(list_0n)) # разделитель в чч_мм two_points = dictionary([":"]) separator = dictionary([":", "."]) # определяем предлоги pr_v = rule("в") pr_ok = rule("около") pr_vrayone = morph_pipeline(["В районе"]) pr_k = rule("к") pr_na = rule("на") pr_c = rule("с") start_prepositions = or_(pr_ok, pr_v, pr_k, pr_na, pr_c, pr_vrayone) pr_vtech = morph_pipeline(["в течение"]) pr_do = rule("до") pr_po = rule("по") duration_prepositions = or_(pr_vtech, pr_do, pr_po) # отрезки времени суток day_periods = or_(rule(normalized("утро")), rule(normalized("день")), rule(normalized("вечер"))) # час - особый случай, т.к. сам обозначает определённое время или длительность(аналогично "человк") hour = rule(normalized("час")) people = rule(normalized("человек")) # слова перед временем начала start_syn = dictionary([ "начало", "старт", "встреча", "переговорную", "переговорку", "пропуск" ]) start_verbs = dictionary([ "начать", "прийти", "заказать", "забронировать", "выделить", "состоится" ]) # слова перед продолжительнотью duration_verbs = dictionary(["займёт", "продлится"]) # слова перед временем конца end_verbs = dictionary(["закончить", "уйдём", "завершим"]) end_syn = dictionary(["конец", "окончание", "завершение"]) # для поиска времени начала, которое выделяется с помощью : или - start_with_separator = or_(rule("начало"), rule("старт"), rule("время"), morph_pipeline(["начало встречи"]), morph_pipeline(["старт встречи"]), morph_pipeline(["время встречи"])) duration_with_separator = or_( rule("продолжительность"), morph_pipeline(["продолжительность встречи"])) end_with_separator = or_(rule("конец"), rule("окончание"), rule("завершение"), morph_pipeline(["конец встречи"]), morph_pipeline(["окончание встречи"]), morph_pipeline(["завершение встречи"])) # относительные указатели на день(относительно сегодняшнего) day_pointer = or_(rule("понедельник"), morph_pipeline(["пн."]), rule("пн"), rule("вторник"), morph_pipeline(["вт."]), rule("вт"), rule("среда"), rule("среду"), morph_pipeline(["ср."]), rule("ср"), rule("четверг"), morph_pipeline(["чт."]), rule("чт"), rule("пятница"), rule("пятницу"), morph_pipeline(["пт."]), rule("пт"), rule("суббота"), rule("субботу"), morph_pipeline(["сб."]), rule("сб"), rule("воскресение"), rule("воскресенье"), morph_pipeline(["вс."]), rule("вс"), rule("завтра"), rule("послезавтра"), rule("сегодня")) # чужие слова self._foreignWords = [ "этаж", "январь", "февраль", "март", "апрель", "май", "июнь", "июль", "август", "сентябрь", "октябрь", "ноябрь", "декабрь" ] # количественные числительные в числа self._Counts = { "человек": 1, "1": 1, "один": 1, "два": 2, "2": 2, "двое": 2, "вдвоём": 2, "трое": 3, "три": 3, "3": 3, "втроём": 3, "четверо": 4, "четыре": 4, "4": 4, "вчетвером": 4, "5": 5, "пять": 5, "пятеро": 5, "впятером": 5, "6": 6, "шесть": 6, "шестеро": 6, "7": 7, "семь": 7, "семеро": 7, "8": 7, "восемь": 8, "9": 7, "девять": 9, "10": 7, "десять": 10 } # приведение времени к номальной форме self._ToNormalHours = { "08.00": "08:00", "8": "08:00", "восемь": "08:00", "09.00": "09:00", "9": "09:00", "девять": "09:00", "10.00": "10:00", "10": "10:00", "десять": "10:00", "11.00": "11:00", "11": "11:00", "одиннадцать": "11:00", "12.00": "12:00", "12": "12:00", "двенадцать": "12:00", "полдень": "12:00", "13.00": "13:00", "1": "13:00", "13": "13:00", "один": "13:00", "час": "13:00", "часу": "13:00", "14.00": "14:00", "2": "14:00", "14": "14:00", "два": "14:00", "15.00": "15:00", "3": "15:00", "15": "15:00", "три": "15:00", "16.00": "16:00", "4": "16:00", "16": "16:00", "четыре": "16:00", "17.00": "17:00", "5": "17:00", "17": "17:00", "пять": "17:00", "18.00": "18:00", "6": "18:00", "18": "18:00", "шесть": "18:00", "19.00": "19:00", "7": "19:00", "19": "19:00", "семь": "19:00" } # приведение промежутка времени к нормальной форме self._ToNormalDelta = { "1": "01:00", "один": "01:00", "час": "01:00", "1:5": "01:30", "полтора": "01:30", "2": "02:00", "два": "02:00", "3": "03:00", "три": "03:00", "4": "04:00", "четыре": "04:00", "5": "05:00", "пять": "05:00", "6": "06:00", "шесть": "06:00", "7": "7:00", "семь": "07:00" } # правила для времени в формате from time to time self._rulesFromTO = [ # from time to time rule(start_prepositions, or_(hour, rule(or_(hours_t, hours_n))), separator.optional(), minutes_n.optional(), or_(day_periods, hour).optional(), duration_prepositions, or_(hours_t, hours_n), separator.optional(), minutes_n.optional()), # чч:мм - чч:мм rule(hours_n, separator, minutes_n, "-", hours_n, separator, minutes_n), # day time to time rule(day_pointer, rule(or_(hours_t, hours_n)), separator.optional(), minutes_n.optional(), or_(day_periods, hour).optional(), duration_prepositions, or_(hours_t, hours_n), separator.optional(), minutes_n.optional()) ] # правила для времени в формате from time on time self._rulesFromOn = [ # from time on n hour rule(start_prepositions, or_(hours_t, hours_n), separator.optional(), minutes_n.optional(), or_(day_periods, hour).optional(), pr_na, or_(hours_t, hours_n), hour.optional()), # from time on hour rule(start_prepositions, or_(hours_t, hours_n), separator.optional(), minutes_n.optional(), or_(day_periods, hour).optional(), pr_na, hour) ] # правила для времени в формате on time from time self._rulesOnFrom = [ # on n hour from time rule(pr_na, or_(hours_t, hours_n), hour, start_prepositions, or_(hours_t, hours_n), separator.optional(), minutes_n.optional(), or_(day_periods, hour).optional()), # on hour from time rule(pr_na, hour, start_prepositions, or_(hours_t, hours_n), separator.optional(), minutes_n.optional(), or_(day_periods, hour).optional()) ] # правила для времени в формате from time self._rulesFrom = [ # day or start or start verb in time rule(or_(day_pointer, rule(start_syn), rule(start_verbs)), start_prepositions, or_(hours_t, hours_n), separator.optional(), minutes_n.optional()), # start with separator rule(start_with_separator, two_points, or_(rule(hours_t), rule(hours_n)), separator.optional(), minutes_n.optional()), # since time day or hour rule(pr_c, or_(rule(hours_t), rule(hours_n)), separator.optional(), minutes_n.optional(), or_(day_periods, hour)), # since hour rule(pr_c, hour), # on n часов day rule(pr_na, or_(hours_t, hours_n), hour.optional(), day_periods), # on час day rule(pr_na, hour, day_periods) ] # правила для времени окончания и продолжительности self._rulesTo = [ # end or end verb in time rule(or_(end_syn, end_verbs), start_prepositions, or_(rule(hours_t), rule(hours_n), hour), separator.optional(), minutes_n.optional()), # duration verb time-time rule(duration_verbs, hours_n.optional(), dictionary(["."]).optional(), minutes_n.optional(), "-", hours_n.optional(), dictionary(["."]).optional(), hour), # duration verb time rule(duration_verbs, or_(hours_t, hours_n), dictionary(["."]).optional(), minutes_n.optional(), hour), # end with separation rule(end_with_separator, two_points, or_(rule(hours_t), rule(hours_n)), separator.optional(), minutes_n.optional()), # duration with separation rule(duration_with_separator, two_points, or_(rule(hours_t), rule(hours_n)), separator.optional(), minutes_n.optional()) ] # общие правила для начального, конечного времени и продолжительности self._rulesCommon = [ # in time + hour or day period rule(or_(pr_v, pr_vrayone, pr_k), or_(hours_t, hours_n), or_(hour, day_periods)), # on time + day period rule(pr_na, or_(hours_t, hours_n), or_(day_periods)), # in hh:mm rule(pr_v, hours_n, separator, minutes_n), # hh:mm rule(hours_n, two_points, minutes_n, or_(day_periods, hour).optional()), # on n hour rule(pr_na, or_(hours_t, hours_n), hour), # on hour rule(pr_na, hour) ] # правила для количества людей self._rulesCount = [ # coll number rule(coll_numbers_dic), # n people rule(or_(hours_t, hours_n).optional()) ] # правила используемые в повторных запросах self._rulesTime = [ # всевозможные форматы времени rule(or_(rule(hours_t), rule(hours_n), hour), separator.optional(), minutes_n.optional()) ] self._rulesPeriod = [ # всевозможные интервалы времени rule(or_(rule(hours_t), rule(hours_n), hour), dictionary(["."]).optional(), minutes_n.optional()) ] self._rulesCountPeople = [ # количественные числительные rule(coll_numbers_dic), # n человек rule(or_(hours_t, hours_n).optional(), people) ]
TEMPSIGN ) ).interpretation( Temperature ) # Flowers Flower = fact( 'Flower', ['color', 'size', 'size_diam_min', 'size_diam_max', 'measurement', 'other'] ) FLOWER_TOKEN = dictionary({ 'цветок' }) SIZE = dictionary({ 'крупный', 'средний', 'мелкий' }).interpretation(Flower.size.normalized()) SIZE_LABEL = morph_pipeline([ 'диаметром', 'в диаметре' ]) MEASURE_LABEL = morph_pipeline([ 'см',