繁体   English   中英

在嵌套括号内从python获取字符串

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM