我正在尝试用指定的字符串替换单词一二和三。我不明白为什么我的代码不起作用。
import re
string = "one,two,three,"
string = re.sub(r',?(.*?),+','aA', string)
print(string)
返回
aAaAaA
但我希望它返回aA,aA,aA,
。我尝试了几个不同的命令,但没有成功包含逗号。
就我而言,选择应该在括号内,因此不应替换逗号。
最佳答案
Why my code doesn't work
您采用一个字符串并搜索满足 ',?(.*?),+'
模式的所有非重叠子字符串(零个或一个 ,
,(捕获到第 1 组)除换行符之外的任何零个或多个字符、1 个或多个逗号),然后将所有这些匹配项替换为 Aa
。没有逗号才符合逻辑,因为它们与 ,+
匹配并消耗。
As far as I am concerned the selection should be inside the parentheses and the commas should therefore not be substituted.
不,如果您想在捕获的组内进行任何替换,则需要使用 re.sub
以及内部回调方法(或 lambda),请参阅 this rather useless demo仅显示功能:
import re
def repl(m):
return "{0}{1}{2}".format(m.group(1), re.sub(r'\w+', 'Aa', m.group(2)), m.group(3))
string = "one,two,three,"
print(re.sub(r'(,?)(.*?)(,+)',repl, string))
print(re.sub(r'(,?)(.*?)(,+)', lambda m: "{0}{1}{2}".format(m.group(1), re.sub(r'\w+', 'Aa', m.group(2)), m.group(3)), string))
还有其他方法可以获取您需要的内容,甚至是非正则表达式的方法。
- 非正则方式:用
,
分割,并用Aa
替换每个非空 block ,并用,
连接回来 - 修复您的正则表达式:删除
,?
因为.*
无论如何都会匹配它,请将.*?(?=,)
与(?=,)
是一个正向前瞻,需要存在逗号,但不消耗它,即不使其成为一场比赛 - 使用捕获和反向引用:
r'.*?(,+)'
具有匹配 1 个或多个逗号的捕获组,而.*?
仅延迟匹配任何除换行符之外的 0 个以上字符,直到第一个、
和r'aA\1'
替换会将整个匹配替换为aA
和第 1 组中保存的逗号 - 最简单:将所有 1+ ASCII 字母 block (与
'[a-z]+'
和flags=re.I
匹配以使其不区分大小写)替换为一个
模式。
请参阅Python demo :
import re
string = "one,two,three,"
res = ",".join(["Aa" if x else "" for x in string.split(",")]) # non-regex way
print(res)
print(re.sub(r'.*?(?=,)',r'aA', string)) #regex: fixed version
print(re.sub(r'.*?(,+)',r'aA\1', string)) #regex: capturing and backreferences
print(re.sub(r'[a-z]+',r'aA', string, flags=re.I)) # a very simple, shortest possible working regex
关于python - 正则表达式在逗号之间选择和替换字符串不包括预期的逗号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40615444/