我正在尝试在Python中对字符串进行比较。我的字符串包含可以通过多种不同方式构建的标题:
'Title'
'Title: Subtitle'
'Title - Subtitle'
'Title, Subtitle'
'Title Subtitle'
是否可以在Python中进行相似性比较,以便它可以确定match('Title: Subtitle', 'Title - Subtitle') = True
? (或者它会被构造)
基本上我正在试图确定它们是否是相同的标题,即使分裂是不同的。
if 'Title: Subtitle' == 'Title - Subtitle':
match = 'True'
else:
match = 'False'
还有一些可能会存储为The Title: The Subtitle
或Title, The: Subtitle, The
,但我认为这可能会增加一些复杂性,我可能会通过重建字符串来解决这个问题。
答案 0 :(得分:10)
您正在尝试做的事情已经在jellyfish包中很好地实现了。
>>> import jellyfish
>>> jellyfish.levenshtein_distance('jellyfish', 'smellyfish')
2
答案 1 :(得分:6)
标准库的difflib
模块提供了一个函数get_close_matches
,它可以进行模糊字符串匹配。
>>> import difflib
>>> difflib.get_close_matches('python', ['snakes', 'thon.py', 'pythin'])
['pythin', 'thon.py'] # ordered by similarity score
答案 2 :(得分:3)
您可以使用in
关键字。这不是相似性比较,而是做你想要的:
s = "Title: Subtitle"
if "Title" in s or "Subtitle" in s:
match = 'True'
else:
match = 'False'
答案 3 :(得分:2)
尝试替换字符,然后检查相等性:
def match(str1, str2):
str1 = str1.replace(' -', '').replace(',', '').replace(':', '')
str2 = str2.replace(' -', '').replace(',', '').replace(':', '')
return str1 == str2
>>> match('Title: Subtitle', 'Title - Subtitle')
True
>>> match('Title: Subtitle', 'Title, Subtitle')
True
>>>
答案 4 :(得分:2)
如果唯一的障碍是标点符号,则问题很简单:只需丢弃非单词字符并比较剩余的单词列表。
s1 = 'Title - Subtitle'
toks1 = re.split(r"^\W+", s1) # keep just the words
toks1 = [ w.lower() for w in toks1 ]
我投入了小套房,因为这也可能有所不同。将相同的内容应用于每个输入并比较列表。
但正如你所指出的那样,可能存在其他差异。如果您的数据真的包含标题(书籍,电影,科学文章),您可以从库中删除文章和常用连词(所谓的“停用词”)开始。例如,“文章标题”被删除为["title", "article"]
。为了处理单词顺序中的其他可能的差异,您可以使用所谓的“词袋”方法,在信息检索中很常见。将标记列表转换为集合,或转换为单词计数字典,以用于多次出现某些单词的情况。以下是一个示例,使用单词计数和nltk
的“停用词”列表作为过滤器。
import nltk
from collections import Counter
stopwords = set(nltk.corpus.stopwords.words("english"))
toks1 = [ t for t in toks1 if t not in stopwords ]
cnt1 = Counter(toks1)
cnt2 = Counter(toks2) # Another title string, processed the same way
if cnt1 == cnt2:
print("The two strings have exactly the same content words")
如果还有更多变化,天空就是极限。近似文本匹配是活跃研究的主题,应用于信息检索,抄袭检测,遗传学等。您可以检查一个标题是否是另一个的子集(可能有人遗漏了副标题)。您可以尝试通过“编辑距离”进行匹配(例如,由其他几个答案提到的“Levenshtein距离”),将其应用于字母或整个单词。您可以尝试TF-IDF评分等信息检索算法。这些只是您可以尝试的一些事项,因此请寻找能够为您完成工作的最简单的解决方案。谷歌是你的朋友。
答案 5 :(得分:1)
我是一名Ruby程序员,因此没有使用Python的经验,但在Ruby中,使用gem Levensthein可以很快解决这个问题。它计算您需要对字符串进行编辑的次数,以获得相同的字符串。
我也看到了Python的等价物,所以看看https://pypi.python.org/pypi/python-Levenshtein
答案 6 :(得分:1)
这应该有效。 Python翻译可以用来取出任何不同的字符。
valid mathematical expressions
答案 7 :(得分:0)
fnmatch.fnmatch
虽然是为Unix文件名匹配而设计的,但也可以使用,请考虑以下示例:
>>> from fnmatch import fnmatch
>>> l
['Title: Subtitle', 'Title - Subtitle', 'Title, Subtitle', 'Title Subtitle']
>>>
>>> all(fnmatch(x, 'Title*Subtitle') for x in l)
True
另一种方法是检查它们是否都匹配re
模式:
>>> import re
>>> l
['Title: Subtitle', 'Title - Subtitle', 'Title, Subtitle', 'Title Subtitle']
>>> all(re.search(r'^Title.*?Subtitle$', x) for x in l)
True