如何从正则表达式中排除某些可能性?

时间:2019-05-12 10:06:34

标签: python regex parsing regex-group lark-parser

对于我要创建的解析器,我使用此正则表达式作为ID的定义:

ID: /[a-z_][a-z0-9]*/i

(对于不熟悉我正在使用的特定解析器的语法的人,“ i”标志仅表示不区分大小写。)

我也有很多关键字,例如:

CALL_KW: "call"
PRINT_KW: "print"

问题在于,由于语法上的某些歧义,有时关键字被视为ID,而我真的不希望它们成为ID。因此,我在考虑是否可以以完全不匹配关键字的方式重写ID的正则表达式。这样的事情有可能吗?

要提供更多背景信息,我使用了Lark Python解析器库。 Lark提供的Earley解析器(与动态词法分析器一起使用)在处理模棱两可的语法时非常灵活且功能强大,但是有时它们会做这种奇怪的事情(并且不确定地是这样!)。因此,我试图通过使关键字从不匹配ID规则来为解析器提供一些帮助。

2 个答案:

答案 0 :(得分:2)

我相信Lark使用普通的Python正则表达式,因此您可以使用否定的超前断言来排除关键字。但是您必须注意不要拒绝以关键字开头的名称:

ID: /(?!(else|call)\b)[a-z_][a-z0-9]*/i

此正则表达式当然可以在Python3中使用:

>>> # Test with just the word
>>> for test_string in ["x", "xelse", "elsex", "else"]:
...   m = re.match(r"(?!(else|call)\b)[a-z_][a-z0-9]*", test_string)
...   if m: print("%s: Matched %s" % (test_string, m.group(0)))
...   else: print("%s: No match" % test_string)
... 
x: Matched x
xelse: Matched xelse
elsex: Matched elsex
else: No match

>>> # Test with the word as the first word in a string
... for test_string in [word + " and more stuff" for word in ["x", "xelse", "elsex", "else"]]:
...   m = re.match(r"(?!(else|call)\b)[a-z_][a-z0-9]*", test_string)
...   if m: print("%s: Matched %s" % (test_string, m.group(0)))
...   else: print("%s: No match" % test_string)
... 
x and more stuff: Matched x
xelse and more stuff: Matched xelse
elsex and more stuff: Matched elsex
else and more stuff: No match

答案 1 :(得分:0)

有几种方法可以将相似的值不传递给ID。 正则表达式1 例如,您可以在表达式中使用捕获组,也许类似于:     ([a-z] + _ [a-z0-9] +) RegEx电路 此链接可帮助您可视化表达式: 正则表达式2 另一种方法是使用:从右边绑定表达式,然后可以使用类似于以下的表达式: (\ w +): 或带有i标志的原始表达式: ([a-z0-9 _] +): 您可以根据需要添加更多边界。