我正在寻找一个Python模块,可以做简单的模糊字符串比较。具体来说,我想知道字符串相似程度的百分比。我知道这是潜在的主观,所以我希望找到一个库,可以做位置比较以及最长的相似字符串匹配,等等。

基本上,我希望找到一些足够简单的东西,可以产生单个百分比,同时仍然可以配置,以便我可以指定要进行哪种类型的比较。


当前回答

正如nosklo所说,使用Python标准库中的difflib模块。

difflib模块可以使用SequenceMatcher()对象的ratio()方法返回序列相似性的度量值。相似度作为0.0到1.0范围内的浮点数返回。

>>> import difflib

>>> difflib.SequenceMatcher(None, 'abcde', 'abcde').ratio()
1.0

>>> difflib.SequenceMatcher(None, 'abcde', 'zbcde').ratio()
0.80000000000000004

>>> difflib.SequenceMatcher(None, 'abcde', 'zyzzy').ratio()
0.0

其他回答

另一种选择是使用最近发布的软件包FuzzyWuzzy。本博客还介绍了包支持的各种功能。

正如nosklo所说,使用Python标准库中的difflib模块。

difflib模块可以使用SequenceMatcher()对象的ratio()方法返回序列相似性的度量值。相似度作为0.0到1.0范围内的浮点数返回。

>>> import difflib

>>> difflib.SequenceMatcher(None, 'abcde', 'abcde').ratio()
1.0

>>> difflib.SequenceMatcher(None, 'abcde', 'zbcde').ratio()
0.80000000000000004

>>> difflib.SequenceMatcher(None, 'abcde', 'zyzzy').ratio()
0.0

下面是一个python脚本,用于计算两个单词的最长公共子字符串(可能需要调整才能用于多词短语):

def lcs(word1, word2):

    w1 = set(word1[i:j] for i in range(0, len(word1))
             for j in range(1, len(word1) + 1))

    w2 = set(word2[i:j] for i in range(0, len(word2))
             for j in range(1, len(word2) + 1))

    common_subs = w1.intersection(w2)

    sorted_cmn_subs = sorted([
        (len(str), str) for str in list(common_subs)
        ])

    return sorted_cmn_subs.pop()[1]

下面是如何使用Charicar的simhash的方法,这也适用于长文档,当你改变文档中的单词顺序时,它也会检测到100%的相似性

http://blog.simpliplant.eu/calculating-similarity-between-text-strings-in-python/

Levenshtein Python扩展和C库。

https://github.com/ztane/python-Levenshtein/

Levenshtein Python C扩展模块包含用于快速的函数 计算 - Levenshtein(编辑)距离,编辑操作 -字符串相似度 -近似中值字符串,通常字符串平均 -字符串序列和集相似度 它支持普通字符串和Unicode字符串。

$ pip install python-levenshtein
...
$ python
>>> import Levenshtein
>>> help(Levenshtein.ratio)
ratio(...)
    Compute similarity of two strings.

    ratio(string1, string2)

    The similarity is a number between 0 and 1, it's usually equal or
    somewhat higher than difflib.SequenceMatcher.ratio(), becuase it's
    based on real minimal edit distance.

    Examples:
    >>> ratio('Hello world!', 'Holly grail!')
    0.58333333333333337
    >>> ratio('Brian', 'Jesus')
    0.0

>>> help(Levenshtein.distance)
distance(...)
    Compute absolute Levenshtein distance of two strings.

    distance(string1, string2)

    Examples (it's hard to spell Levenshtein correctly):
    >>> distance('Levenshtein', 'Lenvinsten')
    4
    >>> distance('Levenshtein', 'Levensthein')
    2
    >>> distance('Levenshtein', 'Levenshten')
    1
    >>> distance('Levenshtein', 'Levenshtein')
    0