特定正则表达式模式匹配Python

2024-09-27 21:27:02 发布

您现在位置:Python中文网/ 问答频道 /正文

发行
我遇到了一个问题,不幸的是我还不太熟悉regex,但是我正在尝试解决一个自动处理文本的问题。实际上,这个问题比下面我要给出的例子要复杂一点,但这主要是为了尽可能地简化它,因为问题在于我的regex能力。你知道吗

假设我们有一个包含两种不同模式的字符串。在这种情况下,AABB它们在字符串中的随机位置。这些模式可能以完全随机的顺序出现零次或多次。你知道吗

例如:
"Hello, this AAis just a BB test string. I'm AA here to test BB the regex."

我要做的是根据以下两个规则搜索“test”并将其替换为“fix”:

  1. 如果在“test”之前只找到AA模式,则“test”不会被替换。你知道吗
  2. 如果在“test”之前只找到BB模式,则“test”替换为“fix”。你知道吗
  3. 如果在“测试”之前出现1个或多个AA和1个或多个BB,那么在这些多个模式中,BB模式必须排在最后。如果是这种情况,“test”将替换为“fix”。你知道吗
  4. 如果没有找到任何模式,那么“test”总是替换为“fix”。你知道吗

示例:
因此,在上述示例中,“test”一词出现了两次。
第一部分是:"Hello, this AAis just a BB test"
规则3适用并通过。这两种模式都是在“测试”前发现的,并以BB结束。你知道吗

第二部分是:Hello, this AAis just a BB test string. I'm AA here to test" 这里第三条规则适用,但没有通过。你知道吗

最终结果是:
"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导致了字符串中最后一个“test”之前的所有结果,而我只是希望匹配一直到第一个“test”匹配,然后慢慢迭代直到最后一个。你知道吗

因此,我将其修改为:[AA]*?.*[BB]+?[^AA]*?test?
基于regex文档,附加一个?使其不贪婪。
这几乎是我想要的,规则2和3都包括在内,但这对规则1不起作用。所以我不太确定如何修复这个正则表达式模式。你知道吗

另外,如何在整个字符串上迭代regex模式并使用回复sub在需要时替换这些词?你知道吗


非常感谢您的帮助。你知道吗


Tags: to字符串testhellostringhere规则模式
1条回答
网友
1楼 · 发布于 2024-09-27 21:27:02

我不认为试图构建一个正则表达式来完成所有的事情是一个富有成效的方法。相反,让我们使用多个正则表达式和一点编程来解决这个问题:

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”的区域和不替换单词“test”的区域。我们得到了每次找到AA的列表和每次找到BB的列表。我们将它们存储为元组(index, pattern)。这样我们就知道哪里可能有状态变化。之后,我把这些合并成一个单独的列表。我还添加了一个sentinel值,我们需要确保稍后实际复制整个字符串。你知道吗

我们知道初始状态不是要替换的,我们从字符串的开头开始。在每次迭代中,我们取字符串的一部分并将其添加到结果中。完成此操作后,我们将根据刚刚匹配“aa”或“bb”的模式更新状态。你知道吗

相关问题 更多 >

    热门问题