与pyparsing匹配的简单嵌套表达式

时间:2017-02-07 00:04:59

标签: python parsing pyparsing

我想匹配一个看起来像这样的表达式:

(<some value with spaces and m$1124any crazy signs> (<more values>) <even more>)

我只是想沿着圆括号()分割这些值。 目前,我可以减少s表达式示例which is far to extensive and not understandable(恕我直言)中的pyparsing开销。

我尽可能使用nestedExpr语句,将其缩减为一行:

import pyparsing as pp
parser = pp.nestedExpr(opener='(', closer=')')
print parser.parseString(example, parseAll=True).asList()

结果似乎也在白色空间分开,我不想要:

  skewed_output = [['<some',
  'value',
  'with',
  'spaces',
  'and',
  'm$1124any',
  'crazy',
  'signs>',
  ['<more', 'values>'],
  '<even',
  'more>']]
expected_output = [['<some value with spaces and m$1124any crazy signs>' 
['<more values>'], '<even more>']]
best_output = [['some value with spaces and m$1124any crazy signs' 
['more vlaues'], 'even more']]

或者,我很乐意接受任何观点,我可以阅读一些可理解的介绍,了解如何包含更详细的解析器(我希望在两者之间提取值) &lt;&gt;括号并匹配它们(请参阅best_output),但之后我可以随时string.strip()

提前致谢!

1 个答案:

答案 0 :(得分:4)

Pyparsing的nestedExpr接受contentignoreExpr个参数,这些参数指定什么是&#34;单个项目&#34;一个s-expr。您可以在此处传递QuotedString。不幸的是,我对docs的两个参数之间的差异不太了解,但是有些实验表明以下代码应该满足您的要求:

import pyparsing as pp

single_value = pp.QuotedString(quoteChar="<", endQuoteChar=">")
parser = pp.nestedExpr(opener="(", closer=")",
                       content=single_value,
                       ignoreExpr=None)

example = "(<some value with spaces and m$1124any crazy signs> (<more values>) <even more>)"
print(parser.parseString(example, parseAll=True))

输出:

[['some value with spaces and m$1124any crazy signs', ['more values'], 'even more']]

它希望列表以(开头,以)结尾,并包含一些可选的以空格分隔的列表或引用的字符串,每个引用的字符串应以<开头,以>并且内部不包含<

您可以更多地使用contentignoreExpr参数来查明content=None, ignoreExpr=single_value使解析接受引用和未引用的字符串(以及单独的带引号的未加引号的字符串):

import pyparsing as pp

single_value = pp.QuotedString(quoteChar="<", endQuoteChar=">")
parser = pp.nestedExpr(opener="(", closer=")", ignoreExpr=single_value, content=None)

example = "(<some value with spaces and m$1124any crazy signs> (<more values>) <even m<<ore> foo (foo) <(foo)>)"
print(parser.parseString(example, parseAll=True))

输出:

[['some value with spaces and m$1124any crazy signs', ['more values'], 'even m<<ore', 'foo', ['foo'], '(foo)']]

有些问题尚待解决:

  1. 为什么pyparsing会忽略连续列表项之间的空格?
  2. contentignoreExpr之间有什么区别,何时应该使用它们?