Учитывая дерево разбора, как я могу извлечь слова, чтобы создать предложение?
Допустим, у меня есть следующий набор входов и выходов:
Входные данные:
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);
Поскольку ваш вопрос помечен синтаксическим деревом, обычным способом будет:
- Определите грамматику для языка. Построить парсер из грамматики.
- Если вы не хотите использовать библиотеки 3-й части, вам придется написать парсер рекурсивного спуска вручную.
- Разобрать выражение в дерево разбора.
- Рекурсивно пройтись по дереву и извлечь каждое слово токена.
Каждый шаг относительно прост в своем собственном праве.