假设我有一个字符串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
的内部操作模式尚未记录,并且我还没有机会深入研究源代码。谢谢!
不是使用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)