python - 如何使用 pyparsing 解析带撇号的语言?
问题描述
我正在尝试使用 pyparsing 解析一种带有撇号的小语言,一切都很顺利,直到突然我开始遇到无法调试的神秘错误。
我已经将我的解析器减少到导致错误的最小部分:
作为我正在尝试做的事情的一个例子,考虑一种带有 1 和嵌套列表的语言。
例如1(11)1(1((11)1))
可以这样解析:
from pyparsing import *
sound=Regex(r"1")
beat=sound ^ nestedExpr(content=sound)
tune=OneOrMore(beat)
print(tune.parseString("1"))
print(tune.parseString("11"))
print(tune.parseString("(1)"))
print(tune.parseString("(1(1))"))
但是如果我尝试添加撇号,那么基本单位是'1
:
例如'1('1'1)'1('1(('1'1)'1))
sound=Regex(r"'1")
beat=sound ^ nestedExpr(content=sound)
tune=OneOrMore(beat)
#These all work as expected
print(tune.parseString("'1"))
print(tune.parseString("'1'1"))
print(tune.parseString("('1)"))
#but
print(tune.parseString("('1('1))"))
导致异常
pyparsing.ParseException: Expected {Re:("'1") ^ nested () expression}, found '1' (at char 5), (line:1, col:6)
谁能告诉我如何使第二个示例像第一个示例一样工作,以便第一个接受的任何字符串在替换 every 后都会被第一个1
接受'1
?
解决方案
nestedExpr
有一个默认值ignoreExpr=quotedString
。这会尝试将前导匹配'
为引号。通过设置禁用它ignoreExpr=None
:
>>> sound=Regex(r"'1")
>>> beat=sound ^ nestedExpr(content=sound, ignoreExpr=None)
>>> tune=OneOrMore(beat)
>>> print(tune.parseString("('1('1))"))
[["'1", ["'1"]]]
推荐阅读
- android - 我是否应该在 Fragments 中使用两个 ViewModel(一个 SharedViewModel 范围为 NavGraphs,另一个 ActivityViewModel 范围为 Activity)
- python - Discord.Py:在 CommandOnCooldown 错误事件上添加冷却时间
- python - 使用正则表达式提取部分文本
- c - (C 语言) 素数分解。如何使输出 2 2 2 3 7 7 变为 2^3 * 3^1 * 7^2?
- vim - 如何在未提及扩展名的vim中转到文件(gf)?
- flutter - flutter-web:通过 Location 插件获取 web 上的位置
- python-3.x - Django 3.1|Python 3.6.12:自定义模板标签没有突然出现?
- elasticsearch - 为什么 elasticsearch 的 Nest 低级搜索方法忽略 SearchDescriptor<>() 对象中定义的类型和索引名称
- c++ - 在链表中使用节点指针如何改变递归?
- r - 数据集中列的网络分析和停用词的使用