我的文字看起来像:
Added "a-foo-b" foo.
目标是使用正则表达式 将第二个 foo 替换为 bar,并保持两个双引号之间的第一个 foo 不变。 所以在上面的文字中,我要寻找的结果是:
Added "a-foo-b" bar.
谢谢
最佳答案
import re
pat = re.compile(r'("[^"]+".*)foo')
s = '''Added "a-foo-b" foo.'''
s_new = re.sub(pat, r'\1bar', s)
print(s_new)
既然你说目标是单独留下双引号,我就把重点放在双引号上。括号组成一个“匹配组”,保存匹配的字符串;这个匹配组匹配双引号和其中的内容,然后模式匹配第二个 foo。替换模式将替换我们匹配的所有内容,但这没关系,因为我们使用 \1
放回匹配组部分,然后我们用 bar
替换第二个 foo
。
如果您知道在要替换的 foo
之后不能再有双引号,这可能是一个更好的模式:
pat = re.compile(r'(".*".*)foo')
这个模式匹配一个双引号,然后是任何东西,然后是另一个双引号。如果引用的字符串包含转义双引号,第一个模式将不起作用,但这个可以。但是如果你在这个字符串上使用这个模式:
s = '''Added "a-foo-b" foo. "Wow, another foo"'''
匹配组将匹配第二个 foo 并匹配第三个 foo,即使它在引号中。这是因为模式匹配是“贪婪的”。
编辑:
问题:是的,如果 s = '''Added "a-foo-b"foo.Deleted "a-foo-b".'''
答案:如果模式总是成立,你知道双引号内不会有转义双引号,你可以使用第一个模式。然后你可以应用多种模式来检测和/或替换你想要的任何东西。下面的pat_added
解决了我们之前想解决的问题;它锚定在字符串的 Added
部分,因此它不会对字符串的 Deleted
部分做任何事情。如果您确实想要匹配和替换引号内的部分字符串,pat_deleted
展示了如何做;它有三个匹配组,把第一个和最后一个放回去让你替换中间的那个。实际上,我们真的不需要中间组的匹配组;我们可以将要替换的部分留在匹配组之外,就像我们对第一个模式所做的那样。
import re
pat_added = re.compile(r'(Added\s+"[^"]+"\s+)\w+')
pat_deleted = re.compile(r'(Deleted\s+"[a-z]-)([^-]+)(-[a-z]"\.)')
s = '''Added "a-foo-b" foo.Deleted "a-foo-b".'''
s = re.sub(pat_added, r'\1bar', s)
s = re.sub(pat_deleted, r'\1bar\3', s)
print(s)
关于python - 正则表达式替换python中的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11258269/