简体   繁体   English

Python RegEx:如何单独替换每个匹配项

[英]Python RegEx: how to replace each match individually

I have a string s , a pattern p and a replacement r , i need to get the list of strings in which only one match with p has been replaced with r .我有一个字符串s ,一个模式p和一个替换r ,我需要得到一个字符串列表,其中只有一个与p匹配被替换为r

Example:例子:

s = 'AbcAbAcc'
p = 'A'
r = '_'

// Output:
['_bcAbAcc', 'Abc_bAcc', 'AbcAb_cc']

I have tried with re.finditer(p, s) but i couldn't figure out how to replace each match with r .我尝试过re.finditer(p, s)但我不知道如何用r替换每个匹配项。

You can replace them manually after finding all the matches:您可以在找到所有匹配项后手动替换它们:

[s[:m.start()] + r + s[m.end():] for m in re.finditer(p,s)]

The result is:结果是:

['_bcAbAcc', 'Abc_bAcc', 'AbcAb_cc']

How does it work?它是如何工作的?

  • re.finditer(p,s) will find all matches (each will be a re.Match object) re.finditer(p,s)将找到所有匹配项(每个匹配项都是一个re.Match对象)
  • the re.Match objects have start() and end() method which return the location of the match re.Match对象有start()end()方法,它们返回匹配的位置
  • you can replace the part of string between begin and end using this code: s[:begin] + replacement + s[end:]您可以使用以下代码替换开始和结束之间的字符串部分: s[:begin] + replacement + s[end:]

You don't need regex for this, it's as simple as你不需要正则表达式,它就像

[s[:i]+r+s[i+1:] for i,c in enumerate(s) if c==p]

Full code: See it working here完整代码: 在这里查看它的工作

s = 'AbcAbAcc'
p = 'A'
r = '_'

x = [s[:i]+r+s[i+1:] for i,c in enumerate(s) if c==p]
print(x)

Outputs:输出:

['_bcAbAcc', 'Abc_bAcc', 'AbcAb_cc']

As mentioned, this only works on one character, for anything longer than one character or requiring a regex, use zvone's answer .如前所述,这仅适用于一个字符,对于超过一个字符或需要正则表达式的任何内容,请使用zvone 的答案

For a performance comparison between mine and zvone's answer (plus a third method of doing this without regex), see here or test it yourself with the code below:有关我的答案和 zvone 的答案之间的性能比较(加上没有正则表达式的第三种方法),请参阅此处或使用以下代码自行测试:

import timeit,re

s = 'AbcAbAcc'
p = 'A'
r = '_'

def x1():
    return [s[:i]+r+s[i+1:] for i,c in enumerate(s) if c==p]

def x2():
    return [s[:i]+r+s[i+1:] for i in range(len(s)) if s[i]==p]

def x3():
    return [s[:m.start()] + r + s[m.end():] for m in re.finditer(p,s)]

print(x1())
print(timeit.timeit(x1, number=100000))
print(x2())
print(timeit.timeit(x2, number=100000))
print(x3())
print(timeit.timeit(x3, number=100000))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM