Кратко: это задача двух частей — (1) получить для каждого слова/токена лемму и синтаксические связи (POS, зависимости), и (2) иметь словарь/список многословных единиц (phrasal verbs, MWE) и правило их сопоставления. Для фразовых глаголов в английском гораздо удобнее опираться на парсер зависимостей (dependency parser), а не на простую сканирующую регулярку по соседним токенам.
Ниже — практическая схема и конкретные инструменты/приёмы.
1) Что нужно из NLP-пайплайна
- Токенизация и разбиение на предложения.
- POS‑тегинг и лемматизация.
- Синтаксический (dependency) парсинг и маркировка MWE/частиц (relations вроде prt / mwe / fixed / compound:prt в UD).
Эти данные позволят надежно обнаруживать фразовые глаголы даже когда частица отделена (I found it out).
Инструменты:
- SpaCy (удобно встраивать в приложение, есть модели en_core_web_* с dependency).
- Stanza / UDPipe (модели UD для многих языков, в том числе сербского).
- UniMorph / Universal Dependencies — стандарты аннотации и готовые деревья/лексиконы.
- Для сербского: есть UD‑модели (Stanza/UDPipe) + морфологические лексиконы; для генерации форм можно использовать Apertium или собственные шаблоны/таблицы.
2) Детекция фразовых глаголов (простая и надёжная схема)
- Сначала получите dependency‑граф предложения.
- Для каждой вершины, чей POS = VERB (или AUX), посмотрите её зависимых токенов.
- Если среди зависимых есть токен с зависимостью prt / compound:prt / mwe (или POS = PART и head = глагол), то это почти всегда фразовый глагол: verb + particle. Примеры:
- „I found out the truth.“ — out будет зависимым от found с rel=prt (или mwe).
- „I found it out yesterday.“ — out всё равно привязан к found, просто между ними стоит местоимение.
- Если частица отделена — dependency покажет связь, поэтому порядок слов не важен.
- Если слово выглядит как предлог (prep/ADP) и у него есть объект (pobj), то это скорее предлог + существительное (PP), не фразовый глагол. Это помогает различать turn up (increase) и turn up (arrive).
3) Что класть в словарь переводов
- Делайте отдельную запись в двуязычном словаре для фразовых глаголов как для единицы: find_out -> «выяснить», turn_up -> «появляться / увеличивать» и т.д.
- При детекции фразового глагола делайте lookup по ключу (verb_lemma + "_" + particle_lemma).
- Учитывайте семантическую неоднозначность: один и тот же сочетание может иметь несколько переводов — можно выбирать по контексту (объект, предлоги вокруг) или показывать список вариантов.
4) Как обрабатывать и показывать пользователю
- На клик по слову:
- Получите предложение.
- Постройте parse.
- Если токен — часть фразового глагола (либо его голова), покажите перевод phrasal_verb (в приоритете над отдельными словами).
- Иначе — лемма → lookup в словаре + сгенерировать перевод с учётом грамм. признаков.
- Для славянских языков: pipeline = morphological analyser → лемматизатор → mapping (лемма + фичи → перевод или шаблон) → генерация целевой словоформы.
- Для английского: обычно проще — минимальная флексия; у вас перевод чаще задаёт форма слова в целевом языке, а не наоборот.
5) Дополнительные приёмы
- Подготовьте большой список phrasal verbs (словари Cambridge, Oxford, списки в открытом доступе). Поместите их в ваше MWE-хранилище.
- Для нестандартных или сложных MWE (идиомы) используйте аналогичный подход: либо статистическое обнаружение MWE (CRF/sequence model), либо ручная база.
- Для ошибок парсера: оставьте fallback — если связь prt не обнаружена, пробегитесь по окну ±3 токена и попытайтесь сопоставить леммы по списку, учитывая допустимость разделителей (pronoun между и т.д.).
- Для различения частицы и предлога ориентируйтесь на POS/rel и наличие объекта у частицы.
6) Ресурсы
- SpaCy (en_core_web_sm, en_core_web_trf) — токенизация, POS, dependency.
- Stanza / UDPipe — UD‑модели для сербского и др.
- Universal Dependencies treebanks — примеры аннотаций phrasal verbs и MWE.
- UniMorph, Apertium — морфогенерация/анализ для флективных языков.
- Списки phrasal verbs (онлайн‑списки, WordNet/VerbNet/PropBank для связей и семантики).
Примерная реализация в псевдокоде (SpaCy‑стиль)
- nlp = spacy.load("en_core_web_sm")
- doc = nlp(sentence)
- tok = doc[word_index]
- if tok.head.pos_ == "VERB" and tok.dep_ in ("prt","mwe","fixed"):
key = tok.head.lemma_ + "_" + tok.lemma_
if key in phrasal_dict: show translation phrasal_dict[key]
else if tok.pos_ == "VERB":
# проверить, есть ли среди зависимых particle
for ch in tok.children:
if ch.dep_ in ("prt","mwe"): key = tok.lemma_ + "_" + ch.lemma_
if key in phrasal_dict: show …
else:
# нормальный словарный lookup по лемме и морф‑признакам
Итого: нет «магической» одной регулярки для всех случаев — надёжно работает сочетание dependency parsing + словарь MWE/phrases. Это простая, понятная и давно применяемая схема (используют в словарных и чтительных приложениях). Если нужно, могу:
- показать пример кода на Python с SpaCy для детекции phrasal verbs,
- подсказать, где взять готовые списки phrasal verbs,
- помочь встроить это в ваш сербско‑русский пайплайн.