kyl*_*tor 3 python regex string recursion hierarchical-data
好吧,我完全不知所措.我有一个依赖树解析工具的输出,如下所示:
(S
(NP
(PRP It)
)
(VP
(VBD said)
(CLAUSE
(S
(NP
(DT the)
(NN figure)
)
(VP
(VBD was)
(VBN rounded)
)
)
)
)
(PUNC .)
)
Run Code Online (Sandbox Code Playgroud)
这些解析输出保存为纯文本.据我所知,输出基本上是二叉树.我想要的是一个输出文件,其中每个单词都在一个新行上,每个单词包含与该单词相关的所有标签.一个例子是:
It S NP PRP
said S VP
the S VP CLAUSE S NP DT
figure S VP CLAUSE S NP NN
was S VP CLAUSE S VP VBD
rounded S VP CLAUSE S VP VBN
. PUNC S
Run Code Online (Sandbox Code Playgroud)
如何将此输出解析为我正在寻找的输出?我试图使用该pyparsing库,并且已经能够将字符串解析为列表的分层列表,但这不符合我的输出需求.
我认为递归可能是一个很好的候选工具,但我不知道如何将它应用于这个问题.任何有关这方面的帮助将不胜感激 - 甚至伪代码来获得实现的想法.
首先,输出转换中存在错误.
要接近解决方案,需要递归.但你不必发明轮子.有一个很好的小模块,pyparsing只是为了这样的任务.我们可以使用递归正则表达式将该字符串转换为嵌套的列表列表:
from pyparsing import nestedExpr
astring = '''(S
(NP
(PRP It)
)
(VP
(VBD said)
(CLAUSE
(S
(NP
(DT the)
(NN figure)
)
(VP
(VBD was)
(VBN rounded)
)
)
)
)
(PUNC .)
)'''
expr = nestedExpr('(', ')')
result = expr.parseString(astring).asList()[0]
print(result)
Run Code Online (Sandbox Code Playgroud)
打印出:
['S',
['NP', ['PRP', 'It']],
['VP',
['VBD', 'said'],
['CLAUSE',
['S',
['NP', ['DT', 'the'], ['NN', 'figure']],
['VP', ['VBD', 'was'], ['VBN', 'rounded']]]]],
['PUNC', '.']]
Run Code Online (Sandbox Code Playgroud)
接下来,我们需要编写一个可以从给定的解析树构建转换的函数.可悲的是,没有简单的方法可以做到这一点.我们需要自己编写一个硬核递归子程序.这是一种方法.使用第n个符号并检索n + 1个符号的所有转换,然后通过将第n个符号附加到这些转换来构建新的转换列表.
听起来有点复杂,但也许代码可以帮助您理解:
def get_rules(rule_list):
transitions = []
if len(rule_list) == 2 and isinstance(rule_list[1], str):
return [rule_list]
for rule in rule_list[1:]:
for r in get_rules(rule):
transitions.append([rule_list[0]] + r)
return transitions
Run Code Online (Sandbox Code Playgroud)
这很简单.有一个基本案例,如果你到达终端,你将返回一个单例转换.否则以递归方式构建转换.
调用此函数并打印结果接下来完成:
for r in get_rules(result):
print(r[-1] + '\t' + '\t'.join(r[:-1]))
Run Code Online (Sandbox Code Playgroud)
输出:
It S NP PRP
said S VP VBD
the S VP CLAUSE S NP DT
figure S VP CLAUSE S NP NN
was S VP CLAUSE S VP VBD
rounded S VP CLAUSE S VP VBN
. S PUNC
Run Code Online (Sandbox Code Playgroud)
我之前提到你的转换表示不正确.你可以用这个交叉检查,这是正确的答案.