问题
我遇到了一个问题,不幸的是我还没有过去熟悉正则表达式,但是我试图解决自动处理文本的问题。实际上这个问题比我下面给出的例子稍微复杂一些,但主要是为了尽可能地简化它,因为问题在于我的正则表达式能力。
假设我们有一个包含两种不同类型模式的字符串。在这种情况下, AA 和 BB ,它们位于字符串中的随机位置。这些模式可以以完全随机顺序存在零次或多次。
例如:
"Hello, this AAis just a BB test string. I'm AA here to test BB the regex."
我想要做的是搜索并替换“#34; test"用"修复"基于以下两条规则:
示例:
所以在上面的例子中,单词" test"出现两次。
第一部分是:"Hello, this AAis just a BB test"
规则3适用并通过。这两种模式都是在"测试之前找到的。它以BB结尾。
第二部分是:Hello, this AAis just a BB test string. I'm AA here to test"
规则3适用但未通过。
最终结果是:
"Hello, this AAis just a BB fix string. I'm AA here to test BB the regex."
不同解决方案:
现在,还有其他方法可以实现这一目标。例如,计算多少次" test"是一个字符串,并做一些for循环,我跟踪哪个模式最后(如果它们存在),直到我找到" test"并根据最后一个采取行动。重复这个过程,直到" test"被发现但这感觉非常低效。
我尝试使用正则表达式解决方案
最初,我的问题是一切都很贪婪。因此[AA]*.*[BB]*.[^AA]+test
导致了所有内容,直到最后一次测试为止。当我想要比赛直到第一次"测试"匹配并慢慢迭代,直到我到达最后一个。
所以,我把它修改为:[AA]*?.*[BB]+?[^AA]*?test?
基于正则表达式文档,附加?
使其变得非贪婪
这几乎是我想要的,规则2和3都被覆盖,但这对规则1不起作用。所以我不太确定如何修复这个正则表达式模式。
另外,如何在整个字符串上迭代我的正则表达式模式并在需要时使用re.sub替换单词?
非常感谢任何帮助。
答案 0 :(得分:1)
我不认为尝试构建一个正则表达式来做所有事情将是一个富有成效的方法。相反,让我们使用多个正则表达式和一些编程来解决问题:
def replace_test(string):
aa_locs = [(m.start(), "aa") for m in re.finditer(AA, string)]
bb_locs = [(m.start(), "bb") for m in re.finditer(BB, string)]
merged = sorted(aa_locs + bb_locs + [len(string), "end"])
start = 0
result = ""
replacing = False
for end, pattern_type in merged:
if replacing:
result += string[start:end].replace("test", "fix")
else:
result += string[start:end]
if pattern_type == "bb":
replacing = True
start = end
return result
它有点复杂,可能会被清理,但让我解释一下这段代码的作用。首先,我们想要列出每次状态可以改变的列表,以便将字符串分成我们将替换“test”和我们不替换的区域。我们得到每次找到AA的列表以及每次找到BB的列表。我们将这些存储为元组(index, pattern)
。这样我们就知道哪里有可能的状态变化。之后,我将这些合并为一个单一的列表。我还添加了一个sentinel值,我们需要确保以后实际复制整个字符串。
我们知道初始状态不是替换,我们从字符串的开头开始。在每次迭代中,我们取一部分字符串并将其添加到结果中。执行此操作后,我们根据匹配“aa”或“bb”的模式更新状态。