在python中匹配错误拼写的单词与正确的拼写单词

时间:2012-07-19 14:59:40

标签: python regex

我正在构建一个获取传入短信的应用,然后根据关键字,它会查看该关键字是否与正在运行的任何广告系列相关联。我现在的方式是加载一个关键字列表和可能的拼写组合,然后当短信进来时,我会查看所有关键字和组合,看看是否匹配。

如何不使用此方法,而是通过实际查找可能与另一个单词匹配的单词。

让我们说正确的拼写是HAMSTER,通常我会给HMSTER HIMSTER HAMSTAR HAMSTR HAMSTIR等提供竞选选择。

有这样做的聪明方法吗?

仓鼠

“hamstir”.compare_to(“hamster”)?匹配

编辑:

2个字怎么样? 假设我们知道SMS中需要匹配两个词:

纠正第一个字=第一个字

纠正第二个字= AND SECOND WORD

SMS = FIRST WORD SECOND

编辑:

理想情况下,人们应该将逗号分隔的单词发送短信,我会知道在哪里分割并查找单词。

但是,如果他们不喜欢,如果:

独特的关键字 第二个参与者

我怎么知道这些词分裂在哪里?第一个单词可能是3个单词长,第二个单词可能是3个或1个或2个等。

在这些示例中,您将如何使用以下技术找到这两个词?

你会看两次吗?每个需要的参数或关键字一个?

5 个答案:

答案 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)

它产生与第一个例子相同的输出。