python - pyparsing - 如何提前查找不明确的语法(带有/不带时区解析的时间戳)
问题描述
我正在尝试使用 pyparsing 来解析 SQL 方言中的一些时间戳类型。
在这个特定的 sql 方言中,我们有两种时间戳类型——带时区和不带时区。
没有时区的示例:TIMESTAMP WITHOUT TIME ZONE
, TIMESTAMP(3)
, TIMESTAMP
,TIMESTAMP(3) WITHOUT TIME ZONE
时区示例:TIMESTAMP WITH TIME ZONE
, TIMESTAMP(9) WITH TIME ZONE
. 正如您所看到的,唯一的区别是需要明确定义具有时区的那些。
不幸的是,以下匹配不适用于 pyparsing:
(RPAR, LPAR, COMMA) = map(Suppress, "(),")
NUMS = Word(nums)
TIMESTAMP = CaselessKeyword("TIMESTAMP") +
Optional(RPAR + NUMS + LPAR) +
Optional(CaselessKeyword("WITHOUT TIME ZONE"))
TIMESTAMP_WITH_TIMEZONE = CaselessKeyword("TIMESTAMP") +
Optional(RPAR + NUMS + LPAR) +
CaselessKeyword("WITH TIME ZONE")
GRAMMAR = StringStart() + TIMESTAMP | TIMESTAMP_WITH_TIMEZONE + StringEnd()
GRAMMAR.parseString("TIMESTAMP WITHOUT TIMEZONE") # Works fine
GRAMMAR.parseString("TIMESTAMP WITH TIMEZONE") # fails
失败是:
File "/.../lib/python3.8/site-packages/pyparsing.py", line 3814, in parseImpl
raise ParseException(instring, loc, self.errmsg, self)
pyparsing.ParseException: Expected end of text, found 'W' (at char 10), (line:1, col:11)
我认为错误可能是因为此语法需要 1 级前瞻来解决某事是否为TIMESTAMP WITH TIMESTAMP
and TIMESTAMP WITHOUT TIMESTAMP
。当它无法匹配WITH TIMESTAMP
时,它就TIMESTAMP
结束了(显然失败的原因不是字符串的结尾)。在这种情况下我该怎么办?pyparsing 是否有超前能力让我解决这个问题?
解决方案
您还需要在内部“|”周围使用括号 选择:
>>> expr = pp.Literal("a") + pp.Literal("b") | pp.Literal("c") + pp.Literal("d")
>>> expr
{{"a" "b"} | {"c" "d"}}
应该:
GRAMMAR = StringStart() + (TIMESTAMP_WITH_TIMEZONE | TIMESTAMP) + StringEnd()
推荐阅读
- angular - ag-grid中复选框的两种方式数据绑定
- html - My default option don't show in my select
- php - Get current directory name in htaccess and prevent redirection
- javascript - Why can't I retrieve a CSS style property for an element using JS?
- xamarin - MMP : error MM5109: Native linking failed with error code 1. 检查构建日志以获取详细信息
- django - 为什么django redis缓存无法获取redis中的数据
- delphi - Delphi TWebBrowser specify port in url
- excel - 以编程方式打印电子表格中的单元格和注释内容
- android - Kotlin 类型不匹配,必需:x 找到:x?
- java - 如何使用适用于 Android 的 AWS 开发工具包从 Digital Ocean Spaces 下载图像?