pyparsing可以吐出导致ParseException的文本吗?

时间:2016-12-06 07:26:49

标签: debugging exception text-parsing string-parsing pyparsing

使用pyparsing我尝试使用复合表达式解析一些文本,如

# These affect the output of numbers in Arabic; see further RunFontSelector
# For further discussion, please see http://www.docx4java.org/forums/pdf-output-f27/arabic-number-digits-in-pdf-output-t1826.html
# Value can be 'Context'|'National'
docx4j.MicrosoftWindows.Region.Format.Numbers.NativeDigits=National
# Value can be 'Hindi'|'Context'|'Arabic'|'System'; default is Arabic ie 1234
docx4j.MicrosoftWord.Numeral=Arabic

a = pp.Word(pp.alphas).setResultsName('A') b = pp.Word(pp.nums).setResultsName('B') c = pp.Word(pp.alphas).setResultsName('C') expr = a + b + c 因异常而失败

parseString

到目前为止一切顺利。但是,要更好地了解正在发生的事情,是否可以让ParseException: Expected W:(0123...) (at char 7), (line:1, col:8) / pyparsing直接告诉我输入字符串中的字符不匹配? (当然,我可以根据例外文本中的信息自行计算。)

另外可以看到在哪个子表达式(a,b或c)中引发了异常?

1 个答案:

答案 0 :(得分:1)

Pyparsing异常包括一个方法markInputline(),它将打印输入字符串的最后一行和发生异常的标记:

import pyparsing as pp
a = pp.Word(pp.alphas).setResultsName('A')
b = pp.Word(pp.nums).setResultsName('B')
c = pp.Word(pp.alphas).setResultsName('C')
expr = a + b + c
try:
    expr.parseString("lskdjf lskdjf sdlkfj")
except ParseException as pe:
    print(pe.markInputline())

lskdjf >!<lskdjf sdlkfj

(如果您不喜欢'&gt;!&lt;',您可以指定其他标记。)

这是我使用的另一种方法,它利用了ParseException的col和line属性:

alphaword = pp.Word(pp.alphas).setName('alphaword')
numword = pp.Word(pp.nums).setName('numword')
expr = alphaword('A') + numword('B') + alphaword('C')
try:
    expr.parseString('sldkj slkdj sldkj')
except ParseException as pe:
    print(pe.line)
    print(' '*(pe.col-1) + '^')
    print(pe)

sldkj slkdj sldkj
      ^
Expected numword (at char 6), (line:1, col:7)

其他几点:

  • 我使用setName()为表达式自己命名,以便异常消息更具可读性。请注意setName和setResultsName之间的区别。

  • 我使用了调用语法来定义结果名称。在实践中(或者只是出于懒惰)我发现'.setResultsName'方法调用真的有损于代码的语法定义部分。因此,代替expr.setResultsName('xyz'),您只需撰写expr('xyz')