为什么不';t反向引用在Python中工作';当使用替换功能时,s re.sub?

为什么不';t反向引用在Python中工作';当使用替换功能时,s re.sub?,python,regex,python-2.7,Python,Regex,Python 2.7,使用Python 2.7中的re.sub,以下示例使用了一个简单的反向引用: re.sub('-{1,2}', r'\g<0> ', 'pro----gram-files') 我希望以下示例是相同的,但事实并非如此: def dashrepl(matchobj): return r'\g<0> ' re.sub('-{1,2}', dashrepl, 'pro----gram-files') def dashrepl(匹配对象): 返回r'\g' re.sub

使用Python 2.7中的
re.sub
,以下示例使用了一个简单的反向引用:

re.sub('-{1,2}', r'\g<0> ', 'pro----gram-files')
我希望以下示例是相同的,但事实并非如此:

def dashrepl(matchobj):
    return r'\g<0> '
re.sub('-{1,2}', dashrepl, 'pro----gram-files')
def dashrepl(匹配对象):
返回r'\g'
re.sub('-{1,2}',dashrepl',pro----gram files')
这会产生以下意外输出:

'pro\\g<0> \\g<0> gram\\g<0> files'
'pro\\g\\g gram\\g文件'

为什么这两个示例给出不同的输出?我是否遗漏了说明这一点的文档?有没有什么特别的原因使这种行为比我预期的更可取?有没有办法在替换函数中使用反向引用?

如果将函数传递给
re.sub
,它允许您用函数返回的字符串替换匹配项。基本上,
re.sub
根据传递的是函数还是字符串,使用不同的代码路径。是的,这实际上是可取的。考虑您想用<代码> FAU> <代码>代替<代码> Foo<代码>的匹配,以及<代码> BAZ < /C> > <代码> Qux<代码>。然后,您可以将其编写为:

repdict = {'foo':'bar','baz':'qux'}
re.sub('foo|baz',lambda match: repdict[match.group(0)],'foo')
你可以争辩说你可以在两个过程中做到这一点,但是如果
repdict
看起来像
{'foo':'baz','baz':'qux'}


我不认为你可以通过反向引用做到这一点(至少不容易)。

因为有更简单的方法来实现你的目标,你可以使用它们

正如您已经看到的,替换函数将获得一个匹配对象作为它的参数

除其他外,此对象还有一个方法
group()
,可以改为使用该方法:

def dashrepl(matchobj):
    return matchobj.group(0) + ' '
这将给出准确的结果


但你是完全正确的——在这方面你有点困惑:

它们描述了
repl
参数:

repl
可以是字符串或函数;如果它是字符串,则会处理其中的任何反斜杠转义

如果
repl
是一个函数,则为模式的每个非重叠出现调用它。函数接受单个匹配对象参数,并返回替换字符串

您可以将其解释为函数返回的“替换字符串”也将应用于反斜杠转义的处理


但是,由于此处理过程仅针对“它是字符串”的情况进行描述,因此它变得更清晰,但乍一看并不明显。

您可以很容易地从match对象中获取整个字符串或单个组,但是如何获取不在组中的字符串部分?例如,如果正则表达式类似于“begin.*”(groupstart.*?groupstop.*?end),那么如何获得与反向引用相同的功能?@amcnabb--我不知道(我通常不使用反向引用)。这里的问题是你有两个选择。只要高兴:)。在某些情况下,您可以使用两个选项中的任何一个执行相同的操作。在其他情况下,可能只有两个选项中的一个有效。@amcnabb反向引用总是指给定的组。在您的示例中,您使用
match.group(1)
@glglglgl来获得您的组--谢谢,我没有完全理解amcnabb提出的问题,但是通过您的回答,我明白了。+glglglgl,您是对的,我不知道为什么我在这里感到困惑。
def dashrepl(matchobj):
    return matchobj.group(0) + ' '