我正在尝试编写一个正则表达式来替换字符串,如果没有单引号括起来的话。 例如,我想在以下字符串中用FOO替换FOO:
string = "' FOO ' abc 123 ' def FOO ghi 345 ' FOO '' FOO ' lmno 678 FOO '"
所需的输出是:
output = "' FOO ' abc 123 ' def FOO ghi 345 ' XXX '' XXX ' lmno 678 FOO '"
我现在的正则表达式是:
myregex = re.compile("(?<!')+( FOO )(?!')+", re.IGNORECASE)
我想我必须使用外观操作符,但我不明白...正则表达式对我来说太复杂了:D
你能帮助我吗?
答案 0 :(得分:2)
以下是如何做到的:
import re
def replace_FOO(m):
if m.group(1) is None:
return m.group()
return m.group().replace("FOO", "XXX")
string = "' FOO ' abc 123 ' def FOO ghi 345 ' FOO '' FOO ' lmno 678 FOO '"
output = re.sub(r"'[^']*'|([^']*)", replace_FOO, string)
print(string)
print(output)
[编辑]
re.sub
函数将接受字符串模板或函数的替换。如果替换是一个函数,每次找到匹配时它都会调用该函数,传递匹配对象,然后使用返回的值(必须是一个字符串)作为替换字符串。
对于模式本身,在搜索时,如果当前位置有'
,它将匹配并包括下一个'
,否则它将匹配但不包括下一个'
或字符串的结尾。
将在每场比赛中调用替换函数并返回相应的结果。
实际上,现在我想一想,我根本不需要使用一个小组。我可以这样做:
def replace_FOO(m):
if m.group().startswith("'"):
return m.group().replace("FOO", "XXX")
return m.group()
string = "' FOO ' abc 123 ' def FOO ghi 345 ' FOO '' FOO ' lmno 678 FOO '"
output = re.sub(r"'[^']*'|[^']+", replace_FOO, string)
答案 1 :(得分:1)
如果没有可变长度的后视,这很难做到。我不确定python正则表达式是否支持它。无论如何,一个简单的解决方案如下:
使用此正则表达式:(?:[^'\s]\s*)(FOO)(?:\s*[^'\s])
第一个捕获组应返回正确的结果。
如果它始终是一个带有单个空格的引号,就像在您的示例中一样,您可以使用固定长度的lookbehind:(?<=[^'\s]\ )FOO(?=\s*[^'\s])
,它将与您想要的完全匹配。