如何从pyparsing select_parser.py中取回括号和逗号?

时间:2017-12-31 15:27:15

标签: pyparsing

下面是一些采用SQL语句的pyparsing代码示例,并使用select_parser.py example再次打印,但没有括号和逗号。什么是让他们回来的最简单方法?

我认为它删除了逗号和括号,因为它们的定义如下:

LPAR,RPAR,COMMA = map(Suppress,"(),")

所以我修改了它们以定义为符号:

LPAR='('
RPAR=')'
COMMA=','

然后我认为这是因为有delimitedList元素删除了逗号。因此,我命名了每个分隔列表,如果ParseResult有一个名称,则重新插入逗号。 (有没有更简单的方法来检测ParseResult是否是分隔列表?或者更一般地说,它是哪个元素?我看到getName(),但未命名的元素呢?)

修改This example显示将分隔列表与','融合。虽然我必须改变语法中的每个例子,但改变格式的语法会感觉很奇怪。理想情况下,我可以说些什么,"对于每个分隔的列表,请放回逗号。"

但什么是抑制括号?

P.S。我希望输出所有内容,因为我正在前往SQL格式化程序,如果一切顺利的话。

代码:

#!/usr/bin/env python

from select_parser import select_stmt
from pyparsing import ParseResults

def struct_to_list(struct):
    elems = []
    for elem in struct:
        if isinstance(elem, ParseResults):
            elems.extend(struct_to_list(elem))
        else:
            elems.append(elem)
    return elems


stmt = "select (1 and 2) or 3 as one, 4 as two from b"
print struct_to_list(select_stmt.parseString(stmt))

select_stmt.runTests(stmt)

输出:

['SELECT', '1', 'AND', '2', 'OR', '3', 'AS', 'one', '4', 'AS', 'two', 'FROM', 'b']

select (1 and 2) or 3 as one, 4 as two from b
['SELECT', [[[['1', 'AND', '2'], 'OR', '3'], 'AS', 'one'], ['4', 'AS', 'two']], 'FROM', 'b']
- columns: [[[['1', 'AND', '2'], 'OR', '3'], 'AS', 'one'], ['4', 'AS', 'two']]
  [0]:
    [[['1', 'AND', '2'], 'OR', '3'], 'AS', 'one']
    [0]:
      [['1', 'AND', '2'], 'OR', '3']
      [0]:
        ['1', 'AND', '2']
      [1]:
        OR
      [2]:
        3
    [1]:
      AS
    [2]:
      one
  [1]:
    ['4', 'AS', 'two']
- from: ['b']
- table: [['b']]
  [0]:
    ['b']

1 个答案:

答案 0 :(得分:0)

您可以使用originalTextFor重新捕获原始预解析文本。下面是一个使用delimitedList的简单示例,您观察到它删除了分隔符并只返回已解析的列表项:

source = "1,2,3, 4,5"

import pyparsing as pp
expr = pp.delimitedList(pp.pyparsing_common.integer)
print(expr.parseString(source))

给出:

[1, 2, 3, 4, 5]

(注意pyparsing_common.integer有一个附加的解析操作,将字符串值转换为整数,因此它们是整数1,2,3,而不是字符串“1”,“2”,“3”等。 )

如果用originalTextFor包装该表达式,那么即使在解析过程中跳过了嵌入的空格,您也会返回原始解析的文本:

print(pp.originalTextFor(expr).parseString(source))

给出:

['1,2,3, 4,5']