python - 如何检查python中最长的子字符串
问题描述
我有一个文本和一个概念列表,如下所示。
concepts = ["data mining", "data", "data source"]
text = "levels and data mining of dna data source methylation"
我想确定concepts
列表中的 是否在 中text
并将所有出现的地方替换concepts[1:]
为concepts[0]
。因此,上述文本的结果应该是;
"levels and data mining of dna data mining methylation"
我的代码如下所示:
concepts = ["data mining", "data", "data source"]
text = "levels and data mining of dna data source methylation"
if any(word in text for word in concepts):
for terms in concepts[1:]:
if terms in text:
text=text.replace(terms,concepts[0])
text=' '.join(text.split())
print(text)
但是,我得到的输出是;
levels and data mining mining of dna data mining source methylation
看起来这个概念data
被替换data mining
为不正确的。更具体地说,我希望在替换时首先考虑最长的选项。
即使我更改concepts
.
concepts = ["data mining", "data source", "data"]
text = "levels and data mining of dna data source methylation"
if any(word in text for word in concepts):
for terms in concepts[1:]:
if terms in text:
text=text.replace(terms,concepts[0])
text=' '.join(text.split())
print(text)
我得到了上述代码的以下输出。
levels and data mining mining of dna data mining mining methylation
如果需要,我很乐意提供更多详细信息。
解决方案
这里的问题是您的迭代策略,一次替换一个术语。因为您的替换术语包含您要替换的术语之一,所以您最终会替换您在之前的迭代中已经更改为替换术语的内容。
解决这个问题的一种方法是原子地进行所有这些替换,以便它们同时发生,并且输出永远不会影响其他替换的结果。有几个策略:
- 您可以将字符串分解为与您的各种术语匹配的标记,并在事后替换它们(并确保没有任何重叠)。
- 您可以使用对多个选项进行原子替换的函数。
#2 的一个例子是sub()
Pythonre
库的方法。这是它的使用示例:
import re
concepts = ["data mining", "data source", "data"]
text = "levels and data mining of dna data source methylation"
# Sort targets by descending length, so longer targets that
# might contain shorter ones are found first
targets = sorted(concepts[1:], key=lambda x: len(x), reverse=True)
# Use re.escape to generate version of the targets with special characters escaped
target_re = "|".join(re.escape(item) for item in targets)
result = re.sub(target_re, concepts[0], text)
请注意,这仍然会导致data mining mining
您的原始替换集,因为它没有 .mining
之后的现有概念data
。如果您想避免这种情况,您可以简单地将要替换的实际项目也包含为替换目标,以便它在较短的期限之前得到匹配:
import re
concepts = ["data mining", "data source", "data"]
text = "levels and data mining of dna data source methylation"
# Sort targets by descending length, so longer targets that
# might contain shorter ones are found first
#
# !!!No [1:] !!!
#
targets = sorted(concepts, key=lambda x: len(x), reverse=True)
# Use re.escape to generate version of the targets with special characters escaped
target_re = "|".join(re.escape(item) for item in targets)
result = re.sub(target_re, concepts[0], text)
推荐阅读
- mysql - MYSQL 我需要先按列排序,然后根据值出现在另一列/列中的次数来限制结果
- gluon - Gluon Mobile arm 安卓支持
- ios - 如何检测 SwiftUI 视图何时被拖过
- nginx - Nginx 错误日志,如果每小时超过一定数量,则跳过日志记录
- firebase - Firestore - 添加其他文档而不创建副本
- reactjs - 如何在博览会上反应原生导航时隐藏标题导航栏?
- github - 有没有办法将 Github README 视频链接包装在表格单元格中?
- jenkins - 詹金斯中的未知阶段部分“withKubeConfig”
- amazon-web-services - 从除当前设备之外的所有设备注销 AWS 放大
- bash - 我在 tsv 文件中的每个单元格有多个值,如何拆分它们并与另一列中的相应值匹配?