使用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)中引发了异常?
答案 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')
。