使用Parsimonious Python库解析多行文本

我正在尝试使用python简约库解析多行文本.我已经玩了一段时间,无法弄清楚如何有效地处理换行符.下面是一个示例.下面的行为是有道理的.我在次要问题中看到了从Erik Rose开始的this comment,但是我不知道如何实现它而没有错误.感谢您的任何提示…

singleline_text = '''\
FIRST   something cool'''

multiline_text = '''\
FIRST   something very
        cool
SECOND  more awesomeness        
'''

grammar = Grammar(
    """
    bin           = ORDER spaces description
    ORDER         = 'FIRST' / 'SECOND'
    spaces        = ~'\s*'
    description   = ~'[A-z0-9 ]*'
    """)

对于单行输出正常工作,print(grammar.parse(singleline_text))给出:

<Node called "bin" matching "FIRST   something cool">
    <Node called "ORDER" matching "FIRST">
        <Node matching "FIRST">
    <RegexNode called "spaces" matching "   ">
    <RegexNode called "description" matching "something cool">

但是多行提供了问题,根据以上链接我无法解决,print(grammar.parse(multiline_text))提供了:

---------------------------------------------------------------------------
IncompleteParseError                      Traceback (most recent call last)
<ipython-input-123-c346891dc883> in <module>()
----> 1 print(grammar.parse(multiline_text))

/Users/me/anaconda3/lib/python3.6/site-packages/parsimonious/grammar.py in parse(self, text, pos)
    121         """
    122         self._check_default_rule()
--> 123         return self.default_rule.parse(text, pos=pos)
    124 
    125     def match(self, text, pos=0):

/Users/me/anaconda3/lib/python3.6/site-packages/parsimonious/expressions.py in parse(self, text, pos)
    110         node = self.match(text, pos=pos)
    111         if node.end < len(text):
--> 112             raise IncompleteParseError(text, node.end, self)
    113         return node
    114 

IncompleteParseError: Rule 'bin' matched in its entirety, but it didn't consume all the text. The non-matching portion of the text begins with '
        cool
SECOND' (line 1, column 23).

这是我尝试过的一件事,没起作用:

grammar2 = Grammar(
    """
    bin           = ORDER spaces description newline
    ORDER         = 'FIRST' / 'SECOND'
    spaces        = ~'\s*'
    description   = ~'[A-z0-9 \n]*'
    newline       = ~r'#[^\r\n]*'
    """)

print(grammar2.parse(multiline_text))

(从211行堆栈跟踪中截断):

ERROR:root:An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line string', (1, 4))

---------------------------------------------------------------------------
SyntaxError                               Traceback (most recent call last)

...


VisitationError: SyntaxError: EOL while scanning string literal (<unknown>, line 1)

Parse tree:
<Node called "spaceless_literal" matching "'[A-z0-9 
]*'">  <-- *** We were here. ***
    <RegexNode matching "'[A-z0-9 
    ]*'">

解决方法:

看来您需要在语法中重复bin元素:

grammar = Grammar(
    r"""
    one           = bin +
    bin           = ORDER spaces description newline 
    ORDER         = 'FIRST' / 'SECOND'
    newline       = ~"\n*"
    spaces        = ~"\s*"
    description   = ~"[A-z0-9 ]*"i
    """)

这样您就可以解析以下内容:

multiline_text = '''\
FIRST   something very cool
SECOND  more awesomeness      
SECOND  even better
'''
上一篇:python – 简约解析器 – 尝试解析赋值语法时出错


下一篇:Python 之父再发文:构建一个 PEG 解析器