Учитывая дерево разбора, как я могу извлечь слова, чтобы создать предложение?

Допустим, у меня есть следующий набор входов и выходов:

Входные данные:

A full sentence: (S (NP (NNP James)) (VP (VBZ is) (NP (NP (DT a) (NN boy)) (VP (
VBG eating) (NP (NNS sausages)))))) 

Выход:

James is a boy eating sausages 

Входные данные: (NNS Sausages)

Выход: Sausages

Как я мог построить Java-программу, чтобы извлечь слова из каждого, чтобы создать предложение? (Без использования внешних библиотек)

2 ответа

Ты можешь использовать .*?(\\w+)(?:\\)+)

(\\w+)(?:\\)+): захватить один или несколько \\w сопровождаемый одним или несколькими )

где \\w имею в виду [a-zA-Z0-9_] Вы также можете использовать ([a-zA-Z]+)(?:\\)+) захватывать только слова

Примечание: использовать .*?(\\w+)\\)+ чтобы сделать его более эффективным, как указано в комментариях shmosel

JAVA Demo

    String s="(S (NP (NNP James)) (VP (VBZ is) (NP (NP (DT a) (NN boy)) (VP (VBG eating) (NP (NNS sausages))))))";
    System.out.println(s.replaceAll(".*?(\\w+)(?:\\)+)", "$1 ").trim());

Выход:

James is a boy eating sausages

Демо:

const regex = /.*?(\w+)(?:\)+)/g;
const str = `(S (NP (NNP James)) (VP (VBZ is) (NP (NP (DT a) (NN boy)) (VP (VBG eating) (NP (NNS sausages))))))
(NNS Sausages)`;
const subst = `$1 `;

const result = str.replace(regex, subst);

console.log(result);

Поскольку ваш вопрос помечен синтаксическим деревом, обычным способом будет:

  1. Определите грамматику для языка. Построить парсер из грамматики.
  2. Если вы не хотите использовать библиотеки 3-й части, вам придется написать парсер рекурсивного спуска вручную.
  3. Разобрать выражение в дерево разбора.
  4. Рекурсивно пройтись по дереву и извлечь каждое слово токена.

Каждый шаг относительно прост в своем собственном праве.

Другие вопросы по тегам