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']
我有一个关键字列表,想提取文档中可以找到的所有关键字。一个关键字可能是另一个关键字的子串。我试图用 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']