我想根据连词和逗号分割树。例如,当我有VP and VP
或NP and NP
或VP, VP
或NP,NP
时,我想分别提取每个VP或NP。我有以下代码:
List<Tree> subtrees = constituent.subTreeList();
for (int i = 0; i < subtrees.size(); i++) {
String s = "@VP $+ CC $+ @VP";
TregexPattern p = TregexPattern.compile(s);
TregexMatcher m = p.matcher(subtrees.get(i));
while (m.find()) {
m.getMatch().pennPrint();
Tree foundTree = m.getMatch();
System.out.println(m.getMatch());
}
}
但它不适用于以下文字。我的代码出了什么问题?
(VP (VP (VB manage) (NP (NP (DT the) (JJ entire) (NN life) (NN cycle)) (PP (IN of) (NP (PRP$ your) (NNS APIs))))) (CC and) (VP (VB expose) (NP (PRP$ your) (NNS APIs)) (PP (TO to) (NP (JJ third-party) (NNS developers)))))
答案 0 :(得分:1)
这里的主要问题是链式Tregex关系(遵循tgrep和tgrep2的传统)具有特殊的非关联语义:A r1 B r2 C [r3 D]
表示A r1 B
和A r2 C
和{{1 }}。 (这通常对A r3 D
的核心用例有意义,这意味着A节点具有B和C子节点。要获得另一个分组,您需要使用括号。特别是,您需要的模式是{{1} }。
这在关系列表下的Tregex Javadoc中有记载,但我意识到这是一个很容易犯的错误,特别是因为语义相对于典型的数学或编程语言表达式而言非常不标准。 / p>
正如@dantiston所指出的,还有其他一些改进。你应该只在外循环中编译一次模式,就像常规的正则表达式一样。另外,只要让Tregex迭代树的节点而不是构建所有子树的完整列表,你会好得多。这是一些很好的示例代码:
A < B < C