【发布时间】:2018-06-26 12:11:54
【问题描述】:
在许多编程语言中,以下
找到foo([a-z]+)bar并替换为GOO\U\1GAR
将导致整个匹配变为大写。我似乎在 python 中找不到等价物;存在吗?
【问题讨论】:
在许多编程语言中,以下
找到foo([a-z]+)bar并替换为GOO\U\1GAR
将导致整个匹配变为大写。我似乎在 python 中找不到等价物;存在吗?
【问题讨论】:
您可以将一个函数传递给re.sub(),这将允许您执行此操作,这是一个示例:
def upper_repl(match):
return 'GOO' + match.group(1).upper() + 'GAR'
还有一个使用它的例子:
>>> re.sub(r'foo([a-z]+)bar', upper_repl, 'foobazbar')
'GOOBAZGAR'
【讨论】:
你的意思是这样的吗?
>>>x = "foo spam bar"
>>>re.sub(r'foo ([a-z]+) bar', lambda match: r'foo {} bar'.format(match.group(1).upper()), x)
'foo SPAM bar'
作为参考,这里是re.sub 的文档字符串(强调我的)。
返回替换最左边得到的字符串 字符串中模式的非重叠出现由 替换repl。 repl 可以是字符串或可调用的; 如果是字符串,则处理其中的反斜杠转义。 如果是 一个可调用的,它传递了匹配对象并且必须返回 要使用的替换字符串。
【讨论】:
如果你已经有一个替换字符串(模板),你可能不会热衷于用冗长的 m.group(1)+...+m.group(2)+...+m.group(3) 来替换它...有时有一个整洁的小字符串很好。
您可以使用MatchObject 的expand() 函数以与sub() 相同的方式评估匹配的模板,从而尽可能多地保留原始模板。您可以在相关部分使用upper。
re.sub(r'foo([a-z]+)bar', lambda m: 'GOO' + m.expand('\1GAR').upper())
虽然这在上面的示例中不是特别有用,并且对于复杂的情况也没有帮助,但对于具有更多捕获组的较长表达式可能更方便,例如 MAC 地址审查正则表达式,其中您只想确保完全替换是否大写。
【讨论】:
m.expand(r'\1') 有效,而 m.expand('\1') 被视为 ASCII 001(至少在 3.7. 2).
你可以使用这个的一些变体:
s = 'foohellobar'
def replfunc(m):
return m.groups()[0]+m.groups()[1].upper()+m.groups()[2]
re.sub('(foo)([a-z]+)(bar)',replfunc,s)
给出输出:
'fooHELLObar'
【讨论】:
对于那些在谷歌上遇到这个的人......
您还可以使用 re.sub 来匹配重复模式。例如,您可以将带空格的字符串转换为驼峰式:
def to_camelcase(string):
string = string[0].lower() + string[1:] # lowercase first
return re.sub(
r'[\s]+(?P<first>[a-z])', # match spaces followed by \w
lambda m: m.group('first').upper(), # get following \w and upper()
string)
to_camelcase('String to convert') # --> stringToConvert
【讨论】: