65.9K
CodeProject 正在变化。 阅读更多。
Home

一个拼写检查引擎

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (15投票s)

2001年1月7日

viewsIcon

279828

downloadIcon

7028

一个免费的拼写检查引擎,可用于您的 C++ 应用程序。包含当前的美国英语词典。

  • 下载演示项目 - 85 Kb
  • 下载当前的美国英语词典 - 820 Kb
  • 描述

    本项目是我之前提交的拼写检查引擎项目的演进。本项目在核心拼写引擎方面进行了大量增强,并添加了一个“即时拼写检查”编辑控件以及相关的支持对话框(参见上文)。

    本项目尚未完成,仍在进行中。当前版本存在许多需要解决的问题。我的长期目标是将其发展到“商业级质量”。

    我将继续朝着我的目标改进这个引擎。我会继续发布我需要的更新。

    与上一版本相比的更改

    1. 重组了类架构。向核心引擎添加了 CFPSSpellCheckEngineOptionsCFPSDictionary
    2. 创建了 CFPSSpellingEditCtrl(一个 CEdit 派生类)来实现“即时拼写检查”编辑控件。
    3. 创建了选项属性页(参见上文)
    4. 创建了拼写检查对话框(参见上文)
    5. 创建了通用词典。(可在上方下载)
    6. 更新了美国英语词典,改进了单词列表和专有名词。
    7. MetaphoneEx 函数进行了增量更改。
    8. 添加了 EditDistance 函数。
    9. 添加了对区分大小写的词典条目的支持。
    10. 为词典添加了文件头。

    待办事项清单

    1. 重写 EditDistance 算法以提高性能。
    2. 研究词典的压缩选项。
    3. 从编辑控件创建 ATL ActiveX 控件。
    4. 创建基于 COM 的词典支持,以实现语言独立性。
    5. 创建 Rich Edit “即时拼写检查”控件。
    6. 添加自动更正功能。
    7. 添加句子开头识别功能,用于自动大写决策。
    8. 继续改进美国英语词典。
    9. 在词典查找中实现二分查找机制。
    10. 继续改进 MetaphoneEx 函数。
    11. 创建 C# (.net) 版本(当 C# 稳定后)
    12. 等等...

    CFPSSpellCheckEngine 这是核心拼写引擎。它旨在实现语言独立性(目前尚未)。该引擎封装了管理词典、提供建议(通过词典)和维护拼写选项的功能。
    CFPSSpellCheckEngineOptions CFPSSpellCheckEngine 的支持类,实现了存储、保存和加载拼写检查选项的支持。目前,它使用序列化文件来存储选项,但可以轻松更改为 INI 文件或注册表。
    CFPSDictionary 基础词典类。定义了一组对所有词典通用的虚拟函数。此外,还基于当前需求提供了所有虚拟函数的基类实现。该类使用带有文件头和任意数量词典记录的定义文件结构。该类的未来派生类将提供特定语言的支持。
    CDlgSpellChecker CDialog 派生类,实现了拼写检查对话框。目前撤销支持基于编辑控件的撤销支持,而不是拼写检查器的撤销。需要进一步改进。
    CPrShtSpellOptions CPropertySheet 派生类,实现了拼写检查引擎的属性表。
    CPrPgeSpellOptions_General CPropertyPage 派生类,实现了常规选项面板。
    CPrPgeSpellOptions_User CPropertyPage 派生类,实现了用户词典选项面板。
    CPrPgeSpellOptions_Common CPropertyPage 派生类,实现了常见拼写错误选项面板。

    重要支持函数

    void CheckSpellingEdit (CFPSSpellCheckEngine* pEngine, CEdit* pEdit)
    当用户在“即时拼写检查”编辑控件中按下 F7(或配置的)热键时,会调用此函数。它会显示 CDlgSpellChecker 对话框。
    void CheckSpellingRich (CFPSSpellCheckEngine* pEngine, CRichEditCtrl* pEdit)
    当用户在“即时拼写检查”编辑控件中按下 F7(或配置的)热键时,会调用此函数。它会显示 CDlgSpellChecker 对话框。

    注意:此函数当前未被使用,因为 Rich Edit 控件尚未完成。

    int EditDistance(const char *szWord1, const char *szWord2) 此函数接受两个单词,并返回一个近似值,表示用户需要进行多少次更改才能使这两个单词匹配。此函数不是真正的编辑距离算法,而是为该拼写检查应用程序定制的算法。
    void MetaphoneEx(const char *szInput, char *szOutput, int iMaxLen) 此函数接收一个单词,并通过 szOutput 参数返回该单词的修改版 Metaphone 表示。这是对 Lawrence Philips. 最初编写的算法的变体。他的算法的更新版本(double-metaphone)也可用。我已经用这个算法和拼写检查引擎进行了测试,但结果并不理想。它确实提供了快速的结果和高命中率,但平均来说,返回的结果也太多了。不过,我正在考虑将其与 EditDistance 算法结合使用,并将进一步审查。
    void SortMatches(LPCSTR lpszBadWord, CStringList &Matches) 此函数根据列表中单词与 lpszBadWord 指定的拼写错误单词之间的近似编辑距离来排序单词建议列表。

    架构

    核心引擎

    核心拼写检查引擎包含三个类:CFPSSpellCheckEngineCFPSSpellCheckEngineOptionsCFPSDictionary。这些类提供了对词典相关功能的 YS,例如添加单词、删除单词、忽略单词、加载词典、保存词典、检查单词是否在词典中、建议可能的匹配项等。

    核心引擎实现为一个严格的后端引擎。它没有任何用户界面组件。这些类公开的大多数可能发生错误的功能都返回一个 int 返回码。这些返回码定义在 1) FPSSpellCheckerInclude.h 和 2) 特定类的头文件中。应始终检查返回码以确定这些功能的完成状态。

    已特别注意确保这些类非常稳定和健壮。此外,性能考虑因素对这些类的实现至关重要。这些类和函数中几乎没有使用 MFC 代码。

    即时拼写检查编辑控件

    即时拼写检查编辑控件包含在 CFPSSpellingEditCtrl 类中。它派生自 CEdit,并通过 AttachEdit 函数通过子类化现有编辑控件来工作。

    为了提高性能,该控件实现了一个计时器,每当没有用户活动(输入、鼠标点击、滚动等)时,就会检查编辑控件显示部分的拼写。调用 RedrawSpellingErrors 函数进行检查。它仅检查编辑控件的显示部分,并为每个显示的单词调用 DrawSpellingError。如果单词在词典中找不到,此函数将调用 DrawSquiglyI 来绘制单词的波浪线。DrawSquigly 创建一个 FPSSPELLEDIT_ERRORS 类型的结构并将其添加到 m_SpellingErrors 成员列表中。

    OnRButtonDown 函数检查 m_SpellingErrors 以确定何时显示常规弹出菜单以及何时显示拼写检查弹出菜单。从核心引擎返回的建议使用 SortMatches 函数进行排序,以便按编辑距离顺序显示。

    PreTranslateMessage 检查热键(默认为 F7)。可以通过调用 SetHotKey 静态成员函数来自定义。按下热键时,将调用 CheckSpellingEdit 函数来显示拼写检查对话框。

    拼写检查对话框

    拼写检查对话框在 CDlgSpellChecker 类中实现。这是一个基于 IDD_SPELL_CHECK 对话框资源的标准 CDialog 派生类。

    拼写检查对话框模仿了 Microsoft Word 的拼写检查实现。它的布局和功能(在大多数情况下)都相同。此对话框会搜索编辑控件(或 Rich Edit 控件)中的句子,查找拼写错误的单词,并显示带有高亮显示拼写错误单词的句子。

    从核心引擎返回的建议使用 SortMatches 函数进行排序,以便按编辑距离顺序显示。

    如何使用演示

    1. 将提供的文件解压到一个目录(确保提取子目录)。
    2. 确保 USMain.dic 文件位于 \Release 目录中。
    3. 确保 USCommon.dic 文件位于 \Release 目录中。
    4. 从 \Release 目录执行 FPSSpellChecker.exe。

    如何将拼写检查器集成到应用程序中

    1. 在您的应用程序的 InitInstance 函数中,添加对 CFPSSpellingEditCtrl::InitSpellingEngine(NULL) 静态成员函数的调用;或者,用指向拼写检查引擎选项文件的完整路径的字符串代替 NULL
    2. 在您的应用程序的 ExitInstance 函数中,添加对 CFPSSpellingEditCtrl::Terminate 静态成员函数的调用。
    3. 将以下文件添加到您的项目中。
      DlgSpellChecker.cpp DlgSpellChecker.h
      DlgSpellingEditCtrl.cpp DlgSpellingEditCtrl.h
      FPSDictionary.cpp FPSDictionary.h
      FPSSpellCheckEngine.cpp FPSSpellCheckEngine.h
      FPSSpellCheckEngineOptions.cpp FPSSpellCheckEngineOptions.h
      FPSSpellCheckerInclude.cpp FPSSpellCheckerInclude.h
      FPSSpellingEditCtrl.cpp FPSSpellingEditCtrl.h
      PrPgeSpellOptions_Common.cpp PrPgeSpellOptions_Common.h
      PrPgeSpellOptions_General.cpp PrPgeSpellOptions_General.h
      PrPgeSpellOptions_User.cpp PrPgeSpellOptions_User.h
      PrShtSpellOptions.cpp PrShtSpellOptions.h
    4. 将以下资源项复制到您的项目中。
      IDD_SPELL_CHECK
      IDD_SPELL_OPTION_COMMON
      IDD_SPELL_OPTION_GENERAL
      IDD_SPELL_OPTION_USER
    5. 在您的 stdafx.h 文件中包含 "FPSSpellCheckerInclude.h" 文件。
      #include "FPSSpellCheckerInclude.h"
    6. 在窗体或对话框资源上放置一个标准的编辑控件,并为其指定一个唯一的控件 ID(例如 ID_TEST_EDIT)。
    7. 在对话框/窗体类文件中添加一个类型为 CFPSSpellingEditCtrl 的成员变量(例如 m_editTest)。
    8. OnInitDialog 函数中,调用 CFPSSpellingEditCtrlAttachEdit 成员函数(例如 m_editTest.AttachEdit(this, ID_TEST_EDIT);)。

    已知问题

    1. 性能仍未达到所需水平。
    2. 语言支持仅限于美国英语。
    3. EditDistance 函数需要改进。
    4. MetaphoneEx 函数需要改进。
    5. 当滚动控件时,编辑控件存在一个绘制问题,特别是在显示拼写错误“波浪线”时。
    6. 对 Rich Edit 控件的支持不完整。
    © . All rights reserved.