[英]Getting string from python within nested parentheses
我有一个像
(0(1(2(3(4(5 The)(6 room))(7(8 was)(9(10 very)(11 good)))))(12 but))(13(14(15 the )(16食物))(17(18是)(19(20非常)(21不好)))))(22。))
实际上是一棵树:
我想达到给定节点具有字符串的目的,即如果说节点0,我应该收到“房间很好,但是食物很差”。 如果我说节点2,我应该收到“房间很好,但是”,节点5应该是“ The”,依此类推。
我将首先构建明显的树(其中的节点具有子节点,并且可能还有一个字符串有效负载),然后对其进行处理以获取所需的替代项(带有包含子节点的有效负载的字符串)。 例如,草稿(无错误检查&c):
class Node(object):
def __init__(self, n):
self.n = n
self.children = []
self.text = []
self.payload = self.wholestring = ''
def make_payload_tree(astring):
root = Node(-1)
parents = [root]
sit = iter(astring)
for c in sit:
if c=='(':
mkn = []
for c in sit:
if c==' ': break
mkn.append(c)
newnode = Node(int(''.join(mkn)))
parents[-1].children.append(newnode)
parents.append(newnode)
elif c==')':
oldnode = parents.pop()
oldnode.payload = ''.join(oldnode.text)
else:
parents[-1].text.append(c)
return root
您可以大致验证此负载树是否正确,例如:
def print_tree(r, ind=0):
print ' '*ind, r.n, r.payload, r.wholestring
for c in r.children:
print_tree(c, ind + 2)
当然,在这一点上, wholestring
仍将是空字符串。
现在,第二遍使您可以构建wholestring
属性:
def makewhole(node):
for c in node.children:
makewhole(c)
s = node.payload + ' '.join(c.wholestring for c in node.children)
node.wholestring = s.replace(' ', ' ')
并且print_tree
应该验证您是否具有所需的全wholestring
。
现在有趣的部分是进行适当的错误诊断(如果输入字符串中存在任何“语法错误”,则此代码非常脆弱,示例中暗含了其语法,但从未明确指出),但这可能是最好的使用适当的词法分析器和解析器方法完成,而不是像我在此处那样进行临时解析。
您可以使用pyparsing解析字符串:
s='(0 (1 (2 (3 (4 (5 The) (6 room)) (7 (8 was) (9 (10 very) (11 good)))) (12 but)) (13 (14 (15 the) (16 food)) (17 (18 was) (19 (20 very) (21 bad))))) (22 .))'
from pyparsing import *
enclosed = Forward()
nestedParens = nestedExpr('(', ')', content=enclosed)
enclosed << (Word(alphanums+'.') | ',' | nestedParens)
>>> enclosed.parseString(s).asList()
[['0', ['1', ['2', ['3', ['4', ['5', 'The'], ['6', 'room']], ['7', ['8', 'was'], ['9', ['10', 'very'], ['11', 'good']]]], ['12', 'but']], ['13', ['14', ['15', 'the'], ['16', 'food']], ['17', ['18', 'was'], ['19', ['20', 'very'], ['21', 'bad']]]]], ['22', '.']]]
然后适当处理嵌套数据。
第一个问题是如何解析字符串。
每个node
看起来像({number} {word | node node})
,其中number
是\\d+
而word
是[\\w,.]+
。 此描述非常适合递归下降解析器。
第二个问题是,如何存储结果树,以便可以轻松找到节点及其后代。
我建议一个由节点号索引的dict
-像
tree = {
0: (1, 22),
1: (2, 13),
2: (3, 12),
# ...
20: "very",
21: "bad",
22: "."
}
这使您可以直接跳到任何节点,并从那里跟随树来重新创建句子片段。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.