pyparsing 可选子字段
这是关于pyparsing,每个结果的名称的继续讨论。我在使用pyparsing时取得了很好的进展,但在解析SQL的排序子句时遇到了麻烦。问题是,任何字段都可以设置为升序或降序。
所以,一个SQL查询可能看起来像这样:
SELECT a FROM x WHERE a = b ...
ORDER BY c, d
ORDER BY c asc, d
ORDER BY c asc, d desc
ORDER BY c, d asc
我一直在摸索,最终想到的最好办法是:
order_dir = oneOf('asc desc', caseless=True)
...
Optional( CaselessKeyword('order by') + columnNameList('order') + Optional(order_dir)('order_dir'))
...
对于像ORDER BY c asc, d desc
这样的情况,这个匹配表示c
是我首先排序的字段,而asc
是我的排序方向,但没有处理到d
。
我希望输出能像['c asc', 'd desc']
这样,只要我还能把columnNameList
放进去就行。
有没有办法用pyparsing来处理这个?我的问题是不是不够清楚?
1 个回答
1
每个排序的列都有一个列名,和一个可选的排序方向。你可以有多个列,用逗号分开。要把每个列名和排序方向配对在一起,这样它们就不会分开。用逗号分开的东西很适合用pyparsing的delimitedList
来处理。
试着把你的条件改成:
Optional( CaselessKeyword('order by') +
delimitedList(Group(columnNameList('order') +
Optional(order_dir, default="asc")('order_dir')))('orderByColumns')
)
这样你会得到一个名为'orderByColumns'的字段,里面包含了一系列的配对。即使你没有写asc(升序)或desc(降序),Optional类的默认设置会自动插入'asc'。你可以这样理解这些列:
if result.orderByColumns:
for ocol in result.orderByColumns:
print "Order by %(order)s (%(order_dir)s)" % ocol
(所有内容未经测试)