解析嵌套列表并为每个有效列表返回原始字符串

问题描述 投票:0回答:1

假设我有一个字符串s = '{aaaa{bc}xx{d{e}}f}',它具有嵌套列表的结构。我想为其提供层次结构表示,同时能够访问与有效子列表相对应的子字符串。为了简单起见,让我们忘记层次结构,我只想要一个与有效子列表相对应的子字符串列表,例如:

['{aaaa{bc}xx{d{e}}f}', '{bc}', '{d{e}}', '{e}']

使用nestedExpr,可以获得包含所有有效子列表的嵌套结构:

import pyparsing as pp

s = '{aaaa{bc}xx{d{e}}f}'
not_braces = pp.CharsNotIn('{}')
expr = pp.nestedExpr('{', '}', content=not_braces)
res = expr('L0 Contents').parseString(s)
print(res.dump())

打印:

[['aaaa', ['bc'], 'xx', ['d', ['e']], 'f']]
- L0 Contents: [['aaaa', ['bc'], 'xx', ['d', ['e']], 'f']]
  [0]:
    ['aaaa', ['bc'], 'xx', ['d', ['e']], 'f']
    [0]:
      aaaa
    [1]:
      ['bc']
    [2]:
      xx
    [3]:
      ['d', ['e']]
      [0]:
        d
      [1]:
        ['e']
    [4]:
      f

为了获得已解析元素的原始字符串表示形式,我必须将其包装到pyparsing.originalTextFor()中。但是,这将从结果中删除所有子列表:

s = '{aaaa{bc}xx{d{e}}f}'
not_braces = pp.CharsNotIn('{}')
expr = pp.nestedExpr('{', '}', content=not_braces)
res = pp.originalTextFor(expr)('L0 Contents').parseString(s)
print(res.dump())

打印:

['{aaaa{bc}xx{d{e}}f}']
- L0 Contents: '{aaaa{bc}xx{d{e}}f}'

实际上,originalTextFor()包装器将其中的所有内容弄平了。

问题。 originalTextFor()是否有替代方法可以保留其子解析元素的结构? (最好有一个非丢弃的类似物,可以将其用于为已解析的子表达式创建命名令牌)

请注意,scanString()仅会给我0级子列表,而不会进入内部。我想我可以使用setParseAction(),但是ParserElement的内部操作模式尚未记录,并且我还没有机会深入研究源代码。谢谢!

python nested pyparsing
1个回答
0
投票

不是使用originalTextFor,而是将nestedExpr表达式包装在locatedExpr中:

import pyparsing as pp
parser = pp.locatedExpr(pp.nestedExpr('{','}'))

[locatedExpr将返回3元素的ParseResults:

  • 开始位置
  • 解析值
  • 结束位置

然后您可以将解析动作附加到此解析器以修改解析的令牌,并添加自己的original_string命名结果,其中包含从输入字符串中切出的原始文本:

def extract_original_text(st, loc, tokens):
    start, tokens[:], end = tokens[0]
    tokens['original_string'] = st[start:end]
parser.addParseAction(extract_original_text)

现在使用此解析器来解析和转储结果:

result = parser.parseString(s)
print(result.dump())

打印:

['aaaa', ['bc'], 'xx', ['d', ['e']], 'f']
- original_string: '{aaaa{bc}xx{d{e}}f}'

并使用以下命令访问original_string结果:

print(result.original_string)
© www.soinside.com 2019 - 2024. All rights reserved.