ply lexmatch 正则表达式的分组与普通的 re 不同
我在使用ply这个库时,发现了一个奇怪的问题:在t.lex.lexmatch中存储的token匹配结果和用re模块定义的sre_pattern相比,似乎有些不对劲。具体来说,group(x)的索引似乎偏差了1。
为了说明我遇到的情况,我定义了一个简单的词法分析器:
import ply.lex as lex
tokens = ('CHAR',)
def t_CHAR(t):
r'.'
t.value = t.lexer.lexmatch
return t
l = lex.lex()
(我收到关于t_error的警告,但暂时不去理会。)现在我给词法分析器输入一些内容,得到一个token:
l.input('hello')
l.token()
我得到了一个LexToken(CHAR,<_sre.SRE_Match object at 0x100fb1eb8>,1,0)
。我想看看这个匹配对象:
m = _.value
现在我查看一下组的内容:
m.group()
=> 'h'
,这正是我所期待的。
m.group(0)
=> 'h'
,这也符合我的预期。
m.group(1)
=> 'h'
,但我本来以为不会有这样的组。
把这个和手动创建一个正则表达式进行比较:
import re
p = re.compile(r'.')
m2 = p.match('hello')
这样得到的组就不一样了:
m2.group()
= 'h'
,这也是我所期待的。
m2.group(0)
= 'h'
,这也符合我的预期。
m2.group(1)
返回IndexError: no such group
,这也是我所期待的。
有没有人知道为什么会出现这样的差异呢?
2 个回答
1
我觉得匹配的组是依赖于文件中token函数的位置的,就好像这些组实际上是通过所有声明的token正则表达式累积起来的一样:
t_MYTOKEN1(t):
r'matchit(\w+)'
t.value = lexer.lexmatch.group(1)
return t
t_MYTOKEN2(t):
r'matchit(\w+)'
t.value = lexer.lexmatch.group(2)
return t
5
在PLY的3.4版本中,这个问题的出现跟表达式是如何从文档字符串转换成模式有关。
查看源代码真的很有帮助 - 在lex.py的第746行:
c = re.compile("(?P<%s>%s)" % (fname,f.__doc__), re.VERBOSE | self.reflags)
我不建议在不同版本之间依赖这样的东西 - 这只是PLY工作原理中的一部分神奇。