2

如果没有被单引号包围,我正在尝试编写一个正则表达式来替换字符串。例如,我想在以下字符串中将 FOO 替换为 XXX:

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

你能帮助我吗?

4

2 回答 2

3

这是如何完成的:

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函数将接受字符串模板或函数作为替换。如果替换是一个函数,每次找到匹配时都会调用该函数,传递匹配对象,然后使用返回值(必须是字符串)作为替换字符串。

至于模式本身,当它搜索时,如果'当前位置有 a ,它将匹配到并包括 next ',否则它将匹配到但不包括'字符串的下一个或结尾。

每次匹配都会调用替换函数并返回适当的结果。

其实,现在想来,我根本不需要用组。我可以这样做:

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)
于 2012-08-03T18:16:19.027 回答
2

如果没有可变长度的后视,这很难做到。我不确定 python 正则表达式是否支持它。无论如何,一个简单的解决方案如下:

使用这个正则表达式: (?:[^'\s]\s*)(FOO)(?:\s*[^'\s])

第一个捕获组应该返回正确的结果。

如果这始终是一个引号,后面有一个空格,如在您的示例中,您可以使用固定长度的lookbehind:(?<=[^'\s]\ )FOO(?=\s*[^'\s])这将与您想要的完全匹配。

于 2012-08-03T08:58:40.567 回答