我正在构建一个获取传入短信的应用,然后根据关键字,它会查看该关键字是否与正在运行的任何广告系列相关联。我现在的方式是加载一个关键字列表和可能的拼写组合,然后当短信进来时,我会查看所有关键字和组合,看看是否匹配。
如何不使用此方法,而是通过实际查找可能与另一个单词匹配的单词。
让我们说正确的拼写是HAMSTER,通常我会给HMSTER HIMSTER HAMSTAR HAMSTR HAMSTIR等提供竞选选择。
有这样做的聪明方法吗?
仓鼠
“hamstir”.compare_to(“hamster”)?匹配
编辑:
2个字怎么样? 假设我们知道SMS中需要匹配两个词:
纠正第一个字=第一个字
纠正第二个字= AND SECOND WORD
SMS = FIRST WORD SECOND
编辑:
理想情况下,人们应该将逗号分隔的单词发送短信,我会知道在哪里分割并查找单词。
但是,如果他们不喜欢,如果:
独特的关键字 第二个参与者
我怎么知道这些词分裂在哪里?第一个单词可能是3个单词长,第二个单词可能是3个或1个或2个等。
在这些示例中,您将如何使用以下技术找到这两个词?
你会看两次吗?每个需要的参数或关键字一个?答案 0 :(得分:7)
最简单的解决方案是使用difflib包,它具有get_close_matches
函数用于近似字符串匹配:
import difflib
difflib.get_close_matches(word, possibilities)
答案 1 :(得分:4)
您要找的是Levenshtein Distance。
假设您的广告系列列表不是太大,您可以计算输入字与每个广告系列之间的距离,然后选择最短的广告系列。要过滤掉完全错误的单词,您可能需要设置最小可接受距离,如果最短值仍然超出限制,则丢弃输入。
要计算两个单词之间的距离,您可以尝试其中一个模块:
例如,使用levenshtein.py
:
from levenshtein import levenshtein
campaigns = (
"HAMSTER",
"TWO WORDED",
"FRIDAY",
)
def get_campaign(word):
return min(campaigns, key=lambda x: levenshtein(word, x))
用法:
>>> get_campaign("HAMSTA")
'HAMSTER'
>>> get_campaign("HAM WORDED")
'TWO WORDED'
>>> get_campaign("FROODY")
'FRIDAY'
>>> get_campaign("FRIDAY")
'FRIDAY'
请注意,这是一种非常简单的方法,即使输入完全不同,也总会返回一些内容。
答案 2 :(得分:2)
我使用levenshtein距离来解决类似的问题 见http://en.wikipedia.org/wiki/Levenshtein_distance
def distance(u1, u2):
try:
s1 = unicode(u1)
s2 = unicode(u2)
except:
s1 = u1
s2 = u2
if len(s1) < len(s2):
return distance(u2, u1)
if not s1:
return len(s2)
previous_row = xrange(len(s2) + 1)
for i, c1 in enumerate(s1):
current_row = [i + 1]
for j, c2 in enumerate(s2):
insertions = previous_row[j + 1] + 1 # j+1 instead of j since previous_row and current_row are one character longer
deletions = current_row[j] + 1 # than s2
substitutions = previous_row[j] + (c1 != c2)
current_row.append(min(insertions, deletions, substitutions))
previous_row = current_row
return previous_row[-1]
distance("hamstir", "hamster") < 3
True
distance("god", "hamster") < 3
False
答案 3 :(得分:1)
在我看来,你正试图建立一个拼写检查程序。您可以使用minimum edit distance matching。或者,请查看Peter Norvig's python spell checker
希望有所帮助
答案 4 :(得分:1)
您可以使用模糊匹配和regex
library命名列表,例如,从列表中查找最多一个错误(插入,删除,替换)的任何短语:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import regex as re # pip install regex
words = ["first word", "second word", "third"]
sms = u"junk Furst Word second Third"
for m in re.finditer(ur"(?fie)\L<words>{e<=1}", sms, words=words):
print(m[0]) # the match
print(m.span()) # return indexes where the match found in the sms
# to find out which of the words matched:
print(next(w for w in words
if re.match(ur"(?fi)(?:%s){e<=1}" % re.escape(w), m[0])))
Furst Word
(5, 14)
first word
Third
(22, 27)
third
或者你可以直接迭代这些词:
for w in words:
for m in re.finditer(ur"(?fie)(?:%s){e<=1}" % re.escape(w), sms):
print(m[0])
print(m.span())
print(w)
它产生与第一个例子相同的输出。