Python - Regex findall 提取所有可能是彼此子串的模式

Python - Regex findall extract all patterns that may be substring of one another

我有一个关键字列表,想提取文档中可以找到的所有关键字。一个关键字可能是另一个关键字的子串。我试图用 re.findall 函数提取,但我得到的不是一个关键字,就是关键字的子字符串。如果'A'和'A B'是关键字,我想把它们都提取出来。

以一个简化的案例为例:

文档是"A B C D"。关键字是 "A", "B", "A B"。我的正则表达式模式的输出如下:

string = "A B C D"
regex = 'A\ B|A|B'
re.findall(regex, string)
>>> ['A B']
string = "A B C D"
regex = 'A|B|A\ B'
re.findall(regex, string)
>>> ['A', 'B']

预期输出为

['A', 'B', 'A B']

更新: 类似post建议用new Python regex module解决重叠的例子

import regex as re
re.findall(r'A\ B|B\ C', 'A B C', overlapped=True)
>>> ['A B', 'B C']

但是解决方案不能解决一个模式是另一个模式的子串的情况:

import regex as re
re.findall(r'A\ B|A', 'A B C', overlapped=True)
>>> ['A B']

预计:

>>> ['A B', 'A']

PS: 更具体地说,我的正则表达式模式就像 "(?<!\w)A\ B(?!\w)|(?<!\w)A(?!\w)" 但我认为简化的情况更清楚。

此模式将在字符串“A B”中找到 3 个匹配项。
我们寻找 space,其中回顾 \bA 和展望 B\b。问题是第二个匹配 returns space 而不是字符串 A B.
您必须将 space 替换为 A B

(\bA\b)|((?<=(\bA)) (?=B\b))|(\bB\b)

在一个关键字是另一个关键字的子字符串的情况下,您将需要遍历您的关键字,因为使用正则表达式的匹配总是会选择一个或另一个(大多数模块,例如 re 会选择第一个匹配项在交替中 - 请参阅 here) 在字符串中的给定点,但绝不会同时出现。您可以遍历关键字以确保使用如下代码找到所有匹配项:

import re
 
string = "A B C D"
keys = ["A", "B", "A B"]
 
matches = []
for k in keys:
    matches += re.findall(re.escape(k), string)
 
print(matches)

输出

['A', 'B', 'A B']

Demo on ideone