【问题标题】:Leveraging Spell Checker on local machine?在本地机器上使用拼写检查器?
【发布时间】:2018-12-28 19:55:28
【问题描述】:

我注意到给定机器(Mac、Linux 或 Windows)上的常见应用程序都有各自的拼写检查器。从各种 IDE 到 MS Word/Office,再到笔记软件,应有尽有。

我正在尝试利用我们各自机器的内置实用程序来分析字符串的语法正确性。看来我不能只使用机器上的东西,而且可能不得不下载一个字典来比较。

我不确定是否有更好的方法来实现这一点。我正在考虑尝试在本地做事,但我并不反对通过 api 或 curl 请求来确定字符串中的单词是否拼写正确。

我在看:

  • LanguageTool(hello wrold未能返回错误)
  • Google 的 tbproxy 似乎无法正常工作
  • 字典/Meriam-Webster 需要 api 密钥才能实现自动化。

我在查看 Node 包并注意到拼写检查模块也封装了单词表。

有没有办法利用内置的机器词典,或者如果我下载一个词典/词表进行比较,那会是理想的吗?

我在想一个单词表可能是最好的选择,但我不想重新发明轮子。其他人做了什么来完成类似的工作?

【问题讨论】:

    标签: python node.js string spell-checking


    【解决方案1】:

    功劳归于 Lukas Knuth。我想给出一个明确的如何使用字典和 nspell。

    安装以下 2 个依赖项:

    npm install nspell dictionary-en-us
    

    这是我为解决问题而编写的示例文件。

    // Node File
    
    //  node spellcheck.js [path]
    //  path: [optional] either absolute or local path from pwd/cwd
    
    //  if you run the file from within Seg.Ui.Frontend/ it works as well.
    //    node utility/spellcheck.js
    //  OR from the utility directory using a path:
    //    node spellcheck.js ../src/assets/i18n/en.json
    
    var fs = require("fs");
    var dictionary = require("dictionary-en-us");
    var nspell = require("nspell");
    var process = require("process");
    // path to use if not defined.
    var path = "src/assets/i18n/en.json"
    
    let strings = [];
    function getStrings(json){
        let keys = Object.keys(json);
        for (let idx of keys){
            let val = json[idx];
            if (isObject(val)) getStrings(val);
            if (isString(val)) strings.push(val)
        }
    }
    
    function sanitizeStrings(strArr){
        let set = new Set();
        for (let sentence of strArr){
            sentence.split(" ").forEach(word => {
                word = word.trim().toLowerCase();
                if (word.endsWith(".") || word.endsWith(":") || word.endsWith(",")) word = word.slice(0, -1);
                if (ignoreThisString(word)) return;
                if (word == "") return;
                if (isNumber(word)) return;
                set.add(word)
            });
        }
        return [ ...set ];
    }
    
    function ignoreThisString(word){
        // we need to ignore special cased strings, such as items with
        //  Brackets, Mustaches, Question Marks, Single Quotes, Double Quotes
        let regex = new RegExp(/[\{\}\[\]\'\"\?]/, "gi");
        return regex.test(word);
    }
    
    function spellcheck(err, dict){
        if (err) throw err;
        var spell = nspell(dict);
        let misspelled_words = strings.filter( word => {
            return !spell.correct(word)
        });
        misspelled_words.forEach( word => console.log(`Plausible Misspelled Word: ${word}`))
        return misspelled_words;
    }
    
    function isObject(obj) { return obj instanceof Object }
    function isString(obj) { return typeof obj === "string" }
    function isNumber(obj) { return !!parseInt(obj, 10)}
    
    function main(args){
        //node file.js path
        if (args.length >= 3) path = args[2]
        if (!fs.existsSync(path)) {
            console.log(`The path does not exist: ${process.cwd()}/${path}`);
            return;
        }
        var content = fs.readFileSync(path)
        var json = JSON.parse(content);
        getStrings(json);
        // console.log(`String Array (length: ${strings.length}): ${strings}`)
        strings = sanitizeStrings(strings);
        console.log(`String Array (length: ${strings.length}): ${strings}\n\n`)
    
        dictionary(spellcheck);
    }
    main(process.argv);
    

    这将返回要查看的字符串子集,它们可能拼写错误或误报。

    误报将表示为:

    • 首字母缩略词
    • 单词的非美国英语变体
    • 例如无法识别的专有名词、星期几和月份。
    • 包含括号的字符串。这可以通过将它们从单词中删除来增强。

    显然,这并不适用于所有情况,但我添加了一个忽略此字符串功能,如果说它包含开发人员希望忽略的特殊单词或短语,您可以利用它。

    这意味着作为节点脚本运行。

    【讨论】:

      【解决方案2】:

      您的问题被标记为 NodeJS 和 Python。这是 NodeJS 的特定部分,但我想它与 python 非常相似。


      Windows(从 Windows 8 开始)和 Mac OS X 确实具有内置的拼写检查引擎。

      • Windows:“Windows 拼写检查 API”是一个 C/C++ API。要在 NodeJS 中使用它,您需要创建一个绑定。
      • Mac OS X:“NSSpellChecker”是 AppKit 的一部分,用于 GUI 应用程序。这是一个 Objective-C API,因此您需要再次创建一个绑定。
      • Linux:这里没有“特定于操作系统的”API。大多数应用程序使用 Hunspell,但也有其他选择。这又是一个 C/C++ 库,因此需要绑定。

      幸运的是,已经有一个名为spellchecker 的模块具有上述所有内容的绑定。这将使用它所安装平台的内置系统,但有多个缺点:

      1) 必须构建原生扩展。这个已经通过 node-pre-gyp 完成了二进制文件,但是需要为特定平台安装这些文件。如果你在 Mac OS X 上开发,运行npm install 来获取包,然后在 Linux 上部署你的应用程序(使用node_modules-目录),它不会工作。

      2) 使用内置拼写检查将使用操作系统规定的默认值,这可能不是您想要的。例如,使用的语言可能由选定的操作系统语言决定。对于 UI 应用程序(例如使用 Electron 构建),这可能没问题,但如果您想用操作系统语言以外的其他语言进行服务器端拼写检查,这可能会很困难。


      在基本层面上,对某些文本进行拼写检查归结为:

      1. 对字符串进行标记(例如,通过空格)
      2. 根据已知正确单词列表检查每个标记
      3. (奖励)收集错误令牌的建议并为用户提供选项。

      您可以自己编写第 1 部分。第 2 部分和第 3 部分需要“已知正确单词列表”或字典。幸运的是,已经有一种格式和工具可以使用它:

      有了这个,您可以选择语言,您无需构建/下载任何本机代码,您的应用程序将在每个平台上以相同的方式运行。如果您在服务器上进行拼写检查,这可能是您最灵活的选择。

      【讨论】:

      • 内容丰富。我认为这可能会给我一个合理的结果。我想要的用例是对我们的 json 字符串进行自动批量拼写检查。听起来使用 nspell 可能是一个不错的选择,并将对其进行更多研究。理想情况下,我正在尝试制作一个 git 门控机制来验证我们的字符串文件,因此它将在我们的服务器上。您是否碰巧有一个简单的示例如何给出一组单词?我将研究找到一个明确的解决方案/如何实施列出的选项之一
      • 如果您使用nspell,只需迭代单词并为每个单词调用correct(word)。该方法返回一个布尔值,指示单词是否拼写正确。但是,对于您的用例,我认为使用任何特定于项目的术语制作一个额外的字典可能是有益的,因为基本字典可能会产生相当多的误报命中。
      • 我会给你一个复选标记并立即竖起大拇指,但我会提交一个答案,逐步明确说明如何处理 nspell 等。
      猜你喜欢
      • 1970-01-01
      • 2012-09-04
      • 1970-01-01
      • 1970-01-01
      • 2012-12-05
      • 2012-07-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多