为什么我必须将callable传递给re.sub才能生成大写字符串?

时间:2017-01-12 20:11:12

标签: python regex string

以下是一个有点人为的例子,可以解决我最终的问题......

我想用正则表达式来占用所有格名词的第一个字符。让我们说我有一个正则表达式(可能很差)匹配占有欲的名词。即...

### Regex explanation ###
# 1. match a word break
# 2. match a word-like character and capture in a group
# 3. lookahead for some more characters + the substring "'s"

>>> my_re = re.compile(r"\b(\w)(?=\w+'s)")
>>> re.search(my_re, "bruce's computer")
<_sre.SRE_Match object; span=(0, 1), match='b'>

>>> re.search(my_re, "bruce's computer").group(1)
'b'

对于此示例,它按预期工作。所以,我认为所有必须要做的就是在sub中的第一组调用upper,它应该工作,对吗?

>>> re.sub(my_re, r'\1'.upper(), "bruce's computer")
"bruce's computer"

这不是预期或显而易见的,为什么它不是资本。经过一些研究后,我在re.sub文档中找到了这个......

  

返回通过替换最左边的非重叠获得的字符串   替换repl在字符串中出现模式。 repl可以   是字符串还是可调用的;如果一个字符串,反斜杠在其中逃脱   正在处理中。 如果是可调用的,则传递匹配对象   必须返回要使用的替换字符串。

确实传递一个可调用的确有效......

>>> re.sub(my_re, lambda x: x.group(1).upper(), "bruce's computer")
"Bruce's computer"

大。我想要理解的是,为什么这样做不然我不记得如何在不查找的情况下正确使用API​​来实现这种类型的实例。任何方向都会受到赞赏。

1 个答案:

答案 0 :(得分:3)

第二个参数可以是字符串或可调用的。

re.sub(my_re, r'\1'.upper(), "bruce's computer"):您正在将\1 字符串传递给sub函数(上层或不上层,不重要)< / p>

re.sub(my_re, lambda x: x.group(1).upper(), "bruce's computer"):您正在传递可调用,因此upper()有效,因为它适用于结果。

x.group(1).upper()不会立即评估,因为它包含在lambda表达式中,相当于非lambda:

def func(x):
   return x.group(1).upper()

您也可以传递给re.subre.sub(my_re, func, "bruce's computer"),请注意在这种情况下缺少()