pyparsing 可以吐出导致 ParseException 的文本吗?
Can pyparsing spit out the text which causes a ParseException?
使用pyparsing
我尝试用
这样的复合表达式解析一些文本
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
/parseString
直接告诉我输入字符串 中的 字符不匹配? (当然,我可以根据异常文本中的信息自行计算。)
此外,是否可以查看在哪个子表达式(a、b 或 c) 中引发了异常?
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
(如果您不喜欢'>!<',您可以指定不同的标记。)
这是我使用的另一种方法,它利用了 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')
.
使用pyparsing
我尝试用
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
/parseString
直接告诉我输入字符串 中的 字符不匹配? (当然,我可以根据异常文本中的信息自行计算。)
此外,是否可以查看在哪个子表达式(a、b 或 c) 中引发了异常?
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
(如果您不喜欢'>!<',您可以指定不同的标记。)
这是我使用的另一种方法,它利用了 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')
.