替换包含小写字母的字符

2024-09-20 03:58:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我在堆栈溢出上找到的所有示例对我来说都太复杂,无法进行反向工程

考虑这个玩具例子

s = "asdfasd a_b dsfd"

我想要s = "asdfasd a'b dsfd"

也就是说:找到由下划线分隔的两个字符,并用撇号替换该下划线

尝试:

re.sub("[a-z](_)[a-z]","'",s)
# "asdfasd ' dsfd"

我以为()应该解决这个问题

更令人困惑的是,我们似乎成功地找到了要替换的角色:

re.findall("[a-z](_)[a-z]",s)
#['_']

为什么不更换这个

谢谢


Tags: re角色示例堆栈工程字符例子玩具
3条回答

re.sub将替换它匹配的所有内容

有一种更通用的方法来解决您的问题,您不需要重新修改正则表达式

代码如下:

import re


s = 'Data: year=2018, monthday=1, month=5, some other text'
reg = r"year=(\d{4}), monthday=(\d{1}), month=(\d{1})"


r = "am_replace_str"
def repl(match):
    _reg = "|".join(match.groups())
    return re.sub(_reg, r,match.group(0)) if _reg else r

# 
re.sub(reg,repl, s)

输出:'Data: year=am_replace_str, monthday=am_replace_str, month=am_replace_str, some other text'

当然,如果您的案例不包含组,您的代码可能如下所示:

import re


s = 'Data: year=2018, monthday=1, month=5, some other text'
reg = r"year=(\d{4}), monthday=(\d{1}), month=(\d{1})"


r = "am_replace_str"
def repl(match):
    _reg = "|".join(match.groups())
    return re.sub(_reg, r,match.group(0))

# 
re.sub(reg,repl, s)

使用“向前看”和“向后看”模式:

re.sub("(?<=[a-z])_(?=[a-z])","'",s)

“向前看/向后看”模式的宽度为零,因此不会替换任何内容

UPD:

  • 问题是re.sub将替换整个匹配的表达式,包括前面和下面的字母
  • re.findall仍然匹配整个表达式,但它也有一个组(内括号),您观察到了这一组。整个比赛仍然是a_b
  • lookahead/lookahead表达式检查搜索前/后是否有模式,但不将其包括在匹配中
  • 另一个选择是创建几个组,并将这些组放入替换:re.sub("([a-z])_([a-z])", r"\1'\2", s)

使用re.sub时,必须捕获要保留的文本,而不应捕获要删除的文本

使用

re.sub(r"([a-z])_(?=[a-z])",r"\1'",s)

proof

解释

NODE                     EXPLANATION
                                        
  (                        group and capture to \1:
                                        
    [a-z]                    any character of: 'a' to 'z'
                                        
  )                        end of \1
                                        
  _                        '_'
                                        
  (?=                      look ahead to see if there is:
                                        
    [a-z]                    any character of: 'a' to 'z'
                                        
  )                        end of look-ahead

Python code

import re
s = "asdfasd a_b dsfd"
print(re.sub(r"([a-z])_(?=[a-z])",r"\1'",s))

输出:

asdfasd a'b dsfd

相关问题 更多 >