Python中的不平衡括号重新匹配

2024-10-04 01:26:21 发布

您现在位置:Python中文网/ 问答频道 /正文

使用re.match()时遇到了一个非常奇怪的问题。这是我的代码:

for rule in rules:
    # print (rule, ", ", item)
    if re.match(rule, item):
        tokenLine.append(self.ruleDictionary[rule])
        tokenLine.append("KNOWN")
        break

背景信息:

有一个外部文件包含以下格式的词法规则:

^{pr2}$

ruleDictonary是一个字典,其中production是映射到相关tokenName的键,rules是{}的键列表,item是被读取的字符串。由于某些结果很容易由正则表达式求和,例如[a-z]+\d+,字典键可以是正则表达式定义,这就是这个循环要找出的。在

问题:

目前的情况是,在运行我创建的示例定义文件和示例输入时,我遇到了unbalanced parenthesis错误。但是,当我取消对print()语句前面的print()语句的注释时,它工作得非常好。我创建了print()语句用于调试目的,但没有意识到它会对程序的实际执行产生影响。我完全不知所措,不知道为什么启用了打印功能。在


Tags: 文件代码re示例for字典定义match
2条回答

正如@Kuhess的回答中所描述的,您当前面临的问题是,您的规则包含了paranthesis并将它们用作正则表达式,但却没有逃过paranthesis(或其他在正则表达式中具有特殊含义的字符,如*)。在

但是,这仍然不能解释您观察到的行为,即在尝试匹配规则之前添加一个print()调用似乎可以解决问题。在

我能够从您的回购中复制出unmatched paranthesis错误和^{} branch。然后,在不改变任何东西的情况下,用完全相同的参数进行第二次运行就成功了!在

所以我仔细研究了你的代码,我很确定我知道为什么你的代码是不确定的:你使用一个字典^{})来存储规则,iterate over its keys,和{}一旦规则匹配,循环就存储起来。在

字典在Python中没有保证的顺序。Their order isn't arbitrary,但它几乎不可能预测,它可能会在后续运行之间或甚至在修改字典后发生变化。因此,在某些运行中,有问题的规则永远不会得到测试,因为一个有效的正则表达式匹配,而您break会退出for循环。在

所以,你不能,也永远不应该依赖字典的某个特定顺序。你有什么选择?在

1)使用有序dict(Python 2.7+)

您可以使您的rulesDictionary成为^{}的实例。OrderedDict将按项目插入的顺序保留这些项目:

from collections import OrderedDict
# ...
self.rulesDictionary = OrderedDict()

2)按键动态排序字典项,并按顺序迭代:

^{pr2}$

这将为您提供一个稳定的字母顺序,而不是项目插入的顺序。我相信这些规则的顺序与你的情况有关,所以你应该选择1)。在

您的问题来自模式变量rule的内容。它必须包含一个括号。但是在正则表达式中,括号有特殊的含义(组)。在

所以你需要用\(\)来转义它们。您可以使用:

rule.replace('(', '\(')
rule.replace(')', '\)')

如果你想知道更多,问题Unbalanced parenthesis python中还有其他信息。在

相关问题 更多 >