Python实现单词拼写检查


Posted in Python onApril 25, 2015

这几天在翻旧代码时发现以前写的注释部分有很多单词拼写错误,这些单词错得不算离谱,应该可以用工具自动纠错绝大部分。用 Python 写个拼写检查脚本很容易,如果能很好利用 aspell/ispell 这些现成的小工具就更简单了。

要点

1、输入一个拼写错误的单词,调用 aspell -a 后得到一些候选正确单词,然后用距离编辑进一步?鹧〕龈??返拇省1热缭诵 aspell -a,输入 ‘hella' 后得到如下结果:
hell, Helli, hello, heal, Heall, he'll, hells, Heller, Ella, Hall, Hill, Hull, hall, heel, hill, hula, hull, Helga, Helsa, Bella, Della, Mella, Sella, fella, Halli, Hally, Hilly, Holli, Holly, hallo, hilly, holly, hullo, Hell's, hell's

2、什么是距离编辑(Edit-Distance,也叫 Levenshtein algorithm)呢?就是说给定一个单词,通过多次插入、删除、交换、替换单字符的操作后枚举出所有可能的正确拼写,比如输入 ‘hella',经过多次插入、删除、交换、替换单字符的操作后变成:
‘helkla', ‘hjlla', ‘hylla', ‘hellma', ‘khella', ‘iella', ‘helhla', ‘hellag', ‘hela', ‘vhella', ‘hhella', ‘hell', ‘heglla', ‘hvlla', ‘hellaa', ‘ghella', ‘hellar', ‘heslla', ‘lhella', ‘helpa', ‘hello', …

3、综合上面2个集合的结果,并且考虑到一些理论知识可以提高拼写检查的准确度,比如一般来说写错单词都是无意的或者误打,完全错的单词可能性很小,而且单词的第一个字母一般不会拼错。所以可以在上面集合里去掉第一个字母不符合的单词,比如:'Sella', ‘Mella', khella', ‘iella' 等,这里 VPSee 不删除单词,而把这些单词从队列里取出来放到队列最后(优先级降低),所以实在匹配不了以 h 开头的单词才去匹配那些以其他字母开头的单词。

4、程序中用到了外部工具 aspell,如何在 Python 里捕捉外部程序的输入和输出以便在 Python 程序里处理这些输入和输出呢?Python 2.4 以后引入了 subprocess 模块,可以用 subprocess.Popen 来处理。

5、Google 大牛 Peter Norvig 写了一篇 How to Write a Spelling Corrector 很值得一看,大牛就是大牛,21行 Python 就解决拼写问题,而且还不用外部工具,只需要事先读入一个词典文件。本文程序的 edits1 函数就是从牛人家那里 copy 的。

代码

 

#!/usr/bin/python
# A simple spell checker

import os, sys, subprocess, signal

alphabet = 'abcdefghijklmnopqrstuvwxyz'

def found(word, args, cwd = None, shell = True):
  child = subprocess.Popen(args, 
    shell = shell, 
    stdin = subprocess.PIPE, 
    stdout = subprocess.PIPE, 
    cwd = cwd, 
    universal_newlines = True) 
  child.stdout.readline()
  (stdout, stderr) = child.communicate(word)
  if ": " in stdout:
    # remove \n\n
    stdout = stdout.rstrip("\n")
    # remove left part until :
    left, candidates = stdout.split(": ", 1) 
    candidates = candidates.split(", ")
    # making an error on the first letter of a word is less 
    # probable, so we remove those candidates and append them 
    # to the tail of queue, make them less priority
    for item in candidates:
      if item[0] != word[0]: 
        candidates.remove(item)
        candidates.append(item)
    return candidates
  else:
    return None

# copy from http://norvig.com/spell-correct.html
def edits1(word):
  n = len(word)
  return set([word[0:i]+word[i+1:] for i in range(n)] +           
    [word[0:i]+word[i+1]+word[i]+word[i+2:] for i in range(n-1)] +
    [word[0:i]+c+word[i+1:] for i in range(n) for c in alphabet] +
    [word[0:i]+c+word[i:] for i in range(n+1) for c in alphabet])

def correct(word):
  candidates1 = found(word, 'aspell -a')
  if not candidates1:
    print "no suggestion"
    return 

  candidates2 = edits1(word)
  candidates = []
  for word in candidates1:
    if word in candidates2:
      candidates.append(word)
  if not candidates:
    print "suggestion: %s" % candidates1[0]
  else:
    print "suggestion: %s" % max(candidates)

def signal_handler(signal, frame):
  sys.exit(0)

if __name__ == '__main__':
  signal.signal(signal.SIGINT, signal_handler)
  while True:
    input = raw_input()
    correct(input)

更简单的方法

当然直接在程序里调用相关模块最简单了,有个叫做 PyEnchant 的库支持拼写检查,安装 PyEnchant 和 Enchant 后就可以直接在 Python 程序里 import 了:

>>> import enchant
>>> d = enchant.Dict("en_US")
>>> d.check("Hello")
True
>>> d.check("Helo")
False
>>> d.suggest("Helo")
['He lo', 'He-lo', 'Hello', 'Helot', 'Help', 'Halo', 'Hell', 'Held', 'Helm', 'Hero', "He'll"]
>>>
Python 相关文章推荐
Python程序设计入门(1)基本语法简介
Jun 13 Python
web.py在SAE中的Session问题解决方法(使用mysql存储)
Jun 24 Python
Python探索之静态方法和类方法的区别详解
Oct 27 Python
Python 查看文件的读写权限方法
Jan 23 Python
Python异常对代码运行性能的影响实例解析
Feb 08 Python
Python3 SSH远程连接服务器的方法示例
Dec 29 Python
python实现翻转棋游戏(othello)
Jul 29 Python
Python环境Pillow( PIL )图像处理工具使用解析
Sep 12 Python
python使用ctypes调用扩展模块的实例方法
Jan 28 Python
pyecharts绘制中国2020肺炎疫情地图的实例代码
Feb 12 Python
总结Python常用的魔法方法
May 25 Python
解析python中的jsonpath 提取器
Jan 18 Python
在Debian下配置Python+Django+Nginx+uWSGI+MySQL的教程
Apr 25 #Python
使用PDB简单调试Python程序简明指南
Apr 25 #Python
Python脚本判断 Linux 是否运行在虚拟机上
Apr 25 #Python
在Python中使用cookielib和urllib2配合PyQuery抓取网页信息
Apr 25 #Python
使用Python的Tornado框架实现一个一对一聊天的程序
Apr 25 #Python
使用Python发送邮件附件以定时备份MySQL的教程
Apr 25 #Python
安装Python的web.py框架并从hello world开始编程
Apr 25 #Python
You might like
php基础知识:控制结构
2006/12/13 PHP
探讨file_get_contents与curl效率及稳定性的分析
2013/06/06 PHP
PHP调用Linux命令权限不足问题解决方法
2015/02/07 PHP
php自动给网址加上链接的方法
2015/06/02 PHP
帝国cms常用标签汇总
2015/07/06 PHP
PHP使用逆波兰式计算工资的方法
2015/07/29 PHP
完美利用Yii2微信后台开发的系列总结
2016/07/18 PHP
PHP基于IMAP收取邮件的方法示例
2017/08/07 PHP
js实现的日期操作类DateTime函数代码
2010/03/16 Javascript
基于JavaScript 下namespace 功能的简单分析
2013/07/05 Javascript
js关闭浏览器窗口及检查浏览器关闭事件
2013/09/03 Javascript
js求数组中全部数字可拼接出的最大整数示例代码
2017/08/25 Javascript
JavaScript 下载svg图片为png格式
2018/06/21 Javascript
Vue 项目分环境打包的方法示例
2018/08/03 Javascript
angular ng-model 无法获取值的处理方法
2018/10/02 Javascript
微信小程序日历效果
2018/12/29 Javascript
vue设置导航栏、侧边栏为公共页面的例子
2019/11/01 Javascript
Python实现简单字典树的方法
2016/04/29 Python
Python中functools模块函数解析
2017/03/12 Python
python解析含有重复key的json方法
2019/01/22 Python
Pandas库之DataFrame使用的学习笔记
2019/06/21 Python
python变量的存储原理详解
2019/07/10 Python
Python爬取视频(其实是一篇福利)过程解析
2019/08/01 Python
Python3使用xlrd、xlwt处理Excel方法数据
2020/02/28 Python
简单的Python人脸识别系统
2020/07/14 Python
英国标志性奢侈品牌:Burberry
2016/07/28 全球购物
苹果Mac升级:MacSales.com
2017/11/20 全球购物
北大青鸟学生求职信
2013/09/24 职场文书
物理系毕业生自荐书范文
2014/02/22 职场文书
标枪加油稿
2015/07/22 职场文书
幼儿园小班教师随笔
2015/08/14 职场文书
初中语文教学随笔
2015/08/15 职场文书
《春酒》教学反思
2016/02/22 职场文书
OpenCV全景图像拼接的实现示例
2021/06/05 Python
Python办公自动化解决world文件批量转换
2021/09/15 Python
为Centos安装指定版本的Docker
2022/04/01 Servers