【问题标题】:Why do I have to pass a callable to re.sub to make an uppercase string?为什么我必须将可调用对象传递给 re.sub 才能生成大写字符串?
【发布时间】:2017-01-12 20:11:12
【问题描述】:

下面是一个有点做作的例子,它回答了我最终的问题......

我想使用正则表达式将所有格名词的第一个字符大写。假设我有一个正则表达式(可能很差)匹配所有格名词。即...

### 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 在字符串中出现的模式。复制可以 可以是字符串或可调用的;如果是字符串,则反斜杠在其中转义 被处理。 如果它是可调用的,则传递匹配对象并 必须返回要使用的替换字符串。

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

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

太好了。我想了解的是为什么这会起作用,否则我不记得如何在不查找的情况下正确使用 API 来处理这种类型的实例。任何方向将不胜感激。

【问题讨论】:

  • 在调用 sub 函数之前评估参数。

标签: python regex string


【解决方案1】:

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

re.sub(my_re, r'\1'.upper(), "bruce's computer"):您将\1 字符串 传递给sub 函数(是否高位,无关紧要)

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"),注意在这种情况下缺少()

【讨论】:

  • 谢谢!现在完全有道理,不知道为什么我在问之前没有把它放在脑海里。希望它可以帮助其他人。
  • 这样的错误很多。 Python是宽容的/动态的,所以可以做很多愚蠢的事情。经典的例子是threading.Thread(target=func())。括号使函数被调用,大多数时候返回 None ,并且函数执行,但不在线程中。很难发现!
猜你喜欢
  • 1970-01-01
  • 2011-06-18
  • 2023-03-16
  • 2017-12-08
  • 2017-03-13
  • 1970-01-01
  • 2011-04-21
  • 2015-06-20
  • 1970-01-01
相关资源
最近更新 更多