使用re.match()
遇到一个非常奇怪的问题。这是我的代码:
for rule in rules:
# print (rule, ", ", item)
if re.match(rule, item):
tokenLine.append(self.ruleDictionary[rule])
tokenLine.append("KNOWN")
break
背景信息:
有一个包含词法规则的外部文件,格式为:
tokenName :: production1 | production2 | production3
ruleDictonary
是一个词典,其中的作品是映射到相关tokenName
的键,rules
是ruleDictionary
的键列表,而item
是一个字符串,读。由于某些作品很容易通过正则表达式求和,例如[a-z]+
或\d+
,因此字典键可以是正则表达式定义,也可以是此循环要查找的内容。< / p>
问题:
目前,我在运行示例定义文件和我创建的示例输入时遇到unbalanced parenthesis
错误。但是,当我在print()
语句之前取消注释if
语句时,它完全正常。我为调试目的创建了print()
语句,并没有意识到它会对程序的实际执行产生影响。我完全迷失了,并且在启用打印时不知道它为什么会起作用。
答案 0 :(得分:2)
您的问题来自模式变量rule
的内容。它必须包含一个括号。但在正则表达式中,括号具有特殊含义(组)。
所以你需要使用\(
或\)
来逃避它们。你可以用:
rule.replace('(', '\(')
rule.replace(')', '\)')
如果您想了解更多信息,请在问题Unbalanced parenthesis python中提供其他信息。
答案 1 :(得分:1)
正如在@Kuhess的回答中所描述的那样,你当前的问题是你有包含paranthesis的规则并将它们用作正则表达式,但是没有逃避paranthesis(或其他正则表达式中具有特殊含义的字符,如{{ 1}})。
但是,这仍然没有解释您在尝试匹配规则之前添加*
调用的行为似乎解决了问题。
我能够使用您的回购邮件中的unmatched
branch重现print()
错误。然后,在不改变任何事情的情况下,使用完全相同的参数进行第二次运行!
所以我仔细查看了你的代码,我很确定我知道你的代码是非确定性的原因:你使用字典(self.ruleDictionary
)来存储规则匹配时,规则iterate over its keys和unmatched paranthesis
循环。
字典在Python中没有保证的顺序。 Their order isn't arbitrary,但几乎无法预测,并且可能会在后续运行之间或甚至在修改字典之后发生变化。因此,在某些运行中,有问题的规则永远不会被测试,因为一个有效的正则表达式匹配,而break
循环中的break
匹配。
所以,你不能,也绝不应该依赖字典的特定顺序。那么你有什么选择呢?
1)使用有序的字典(Python 2.7 +)
您可以将for
设为collections.OrderedDict
的实例。 rulesDictionary
将按照插入的顺序保留项目:
OrderedDict
2)按键对字典项进行动态排序,并迭代该有序序列:
from collections import OrderedDict
# ...
self.rulesDictionary = OrderedDict()
这将为您提供稳定的字母顺序,但不会为您插入项目的顺序。我相信这些规则的顺序与你的情况相关,所以你应该选择1)。