如何用匹配的大小写替换正则表达式



当使用正则表达式替换单词时,是否有一种优雅的方法可以指示我希望替换与替换单词的第一个字母的大写/小写匹配?

foo -> bar
Foo -> Bar
foO -> bar

不区分大小写的替换示例,但它不会将Foo正确替换为Bar(而是bar)。

re.sub(r'bfoob', 'bar', 'this is Foo', flags=re.I)
# 'this is bar'

没有开箱即用的东西。您需要使用替换函数。

import re
def cased_replacer(s):
    def replacer(m):
        if m.group(0)[0].isupper():
            return s.capitalize()
        else:
            return s
    return replacer
re.sub(r'bfoob', cased_replacer('bar'), 'this is foo', flags=re.I)
# => 'this is bar'
re.sub(r'bfoob', cased_replacer('bar'), 'this is Foo', flags=re.I)
# => 'this is Bar'

简短回答:不。

长答案:

您可以通过使用 finditer 访问所有匹配项,然后手动执行大小写匹配来执行此操作。

tests = (
        "11foo11",
        "22Foo22",
        "33foO33",
        "44FOO44",
)
import re
foobar = "(?i)(foo)"
for teststr in tests:
    replstr = "bar"
    newchars = list(teststr)
    for m in re.finditer(foobar, teststr):
        mtext = m.group(1)
        replchars = list(replstr)
        for i, ch in enumerate(mtext):
            if ch.isupper():
                replchars[i] = replchars[i].upper()
        newchars[m.start():m.end()] = replchars
        print("Old: ", teststr, " New: ", ''.join(newchars))

最新更新