我试图用pyparsing
来解析这样的结构:
identifier: some description text here which will wrap
on to the next line. the follow-on text should be
indented. it may contain identifier: and any text
at all is allowed
next_identifier: more description, short this time
last_identifier: blah blah
我需要这样的东西:
^{pr2}$但是我很难定义SkipTo
子句的next_identifier
,因为标识符可以自由地出现在描述文本中。在
似乎我需要在语法中包含缩进,这样我就可以跳过下一个没有缩进的行。在
我试过了:
description = pp.Combine(
pp.SkipTo(pp.LineEnd()) +
pp.indentedBlock(
pp.ZeroOrMore(
pp.SkipTo(pp.LineEnd())
),
indent_stack
)
)
但我得到了一个错误:
ParseException: not a subentry (at char 55), (line:2, col:1)
Char 55位于run-on-line的最开始:
...will wrap\n on to the next line...
^
这看起来有点奇怪,因为char位置后面明显跟有空格,这使得它成为一个缩进的子条目。在
我在ipdb中的回溯如下:
5311 def checkSubIndent(s,l,t):
5312 curCol = col(l,s)
5313 if curCol > indentStack[-1]:
5314 indentStack.append( curCol )
5315 else:
-> 5316 raise ParseException(s,l,"not a subentry")
5317
ipdb> indentStack
[1]
ipdb> curCol
1
我应该补充的是,上面我匹配的整个结构也可能缩进了(以未知的量),因此解决方案如下:
description = pp.Combine(
pp.SkipTo(pp.LineEnd()) + pp.LineEnd() +
pp.ZeroOrMore(
pp.White(' ') + pp.SkipTo(pp.LineEnd()) + pp.LineEnd()
)
)
……在我的例子中,这种方法是有效的,因为它会消耗后面的定义。在
使用
indentedBlock
时,传入的参数是块中每一行的表达式,因此它不应该是indentedBlock(ZeroOrMore(line_expression), stack)
,而应该是indentedBlock(line_expression, stack)
。Pyparsing包含一个用于“从这里到行尾的所有内容”的内置表达式,名为restOfLine
,因此我们只将其用于缩进块中每一行的表达式:我们使用ungroup删除由
^{pr2}$indentedBlock
创建的额外级别的嵌套,但是我们还需要删除在indentedBlock
中内部创建的每行嵌套。我们通过一个解析操作来执行此操作:在这一点上,我们已经差不多完成了。以下是解析并转储的示例文本:
或使用此代码拉出“标签”和“说明”字段:
相关问题 更多 >
编程相关推荐