你可以试试amatch。它可以作为 ruby gem 使用,虽然我很长时间没有使用模糊逻辑,但它看起来有你需要的东西。amatch 的主页是:http: //flori.github.com/amatch/。
只是对这个想法感到无聊和混乱,一个完全未经优化和未经测试的解决方案黑客如下:
include 'amatch'
module FuzzyFinder
def scanner( input )
out = [] unless block_given?
pos = 0
input.scan(/(\w+)(\W*)/) do |word, white|
startpos = pos
pos = word.length + white.length
if block_given?
yield startpos, word
else
out << [startpos, word]
end
end
end
def find( text, doc )
index = scanner(doc)
sstr = text.gsub(/\W/,'')
levenshtein = Amatch::Levensthtein.new(sstr)
minlen = sstr.length
maxndx = index.length
possibles = []
minscore = minlen*2
index.each_with_index do |x, i|
spos = x[0]
str = x[1]
si = i
while (str.length < minlen)
i += 1
break unless i < maxndx
str += index[i][1]
end
str = str.slice(0,minlen) if (str.length > minlen)
score = levenshtein.search(str)
if score < minscore
possibles = [spos]
minscore = score
elsif score == minscore
possibles << spos
end
end
[minscore, possibles]
end
end
显然,有许多改进可能而且可能是必要的!一些从顶部:
- 处理文档一次并将结果存储在数据库中。
- 确定初始检查的可用字符串长度,在尝试匹配整个片段之前先处理该初始子字符串。
- 继上一个之后,预先计算该长度的起始片段。