2012-03-22 136 views
10

Id喜欢两个字符串在Ruby中比较,发现它们的相似红宝石比较两个字符串的相似百分比

我有一个看看Levenshtein宝石,但似乎这是最后更新于2008年,我找不到文档如何使用它。随着一些博客暗示其破

我试过text宝石与莱文斯坦,但它提供了一个整数(越小越好)

显然,如果两个字符串的长度是可变的我碰上与Levenshtein算法问题(说比较两个名字,其中一个有中间名,一个没有)。

你会建议我做一个百分比比较?

编辑:林寻找类似的东西PHP的similar text

+0

可能重复的http://stackoverflow.com/questions/4761793/how-to-do-advanced-string-comparison-in-ruby – 2012-03-22 12:17:25

+0

这会生成一个差异列表,即时查找%相似度 – Akshat 2012-03-22 12:19:09

+0

如果字符串长度不同,应该将哪一个作为计算百分比的基础? – 2012-03-22 12:19:51

回答

14

我认为你的问题可以用一些澄清这样做,但这里的东西快速和肮脏(以上计算为较长的字符串,按您的澄清的百分比) :

def string_difference_percent(a, b) 
    longer = [a.size, b.size].max 
    same = a.each_char.zip(b.each_char).select { |a,b| a == b }.size 
    (longer - same)/a.size.to_f 
end 

我仍然不知道有多少意义这个百分比差值你要找的品牌,但是这应该让你至少开始。

这有点像Levensthein距离,因为它比较字符串的字符。所以,如果两个名字只是中间名的不同,他们实际上会有很大的不同。

+0

有人可以解释'相同'位?所以它循环遍历每个字符,而zip为字符串A中的每个字符创建一个数组,并且我期望的是 - 字符串B中的每个字符。第二个each_char如何知道连接到数组的哪个索引? – 2017-03-14 20:26:56

+0

此外,如果在开始时更改了一个字符,则此计算效果不佳。 – 2017-03-14 20:27:23

+1

请谨防Select中的** a **,因为它会清除通过参数传递的变量。最好使用其他字母。 'same = a.each_char。zip(b.each_char).select {| c,d | c == d} .size' – sesperanto 2017-04-26 12:03:11

12

现在有一个ruby gem用于similar_text。 https://rubygems.org/gems/similar_text 它提供了一个similar方法,该方法比较两个字符串并返回一个代表这两个字符串之间百分比相似度的数字。

+2

similar_text gem在大字符串上冻结,尝试143kb html页面 – 2016-07-03 06:38:09

9

我可以推荐fuzzy-string-match宝石。

您可以使用它像这样(从the docs拍摄):

require "fuzzystringmatch" 
jarow = FuzzyStringMatch::JaroWinkler.create(:native) 
p jarow.getDistance("jones", "johnson") 

它会返回一个分值~0.832怎样完成好这些字符串匹配。