在本地计算机上使用拼写检查器?

时间:2018-12-28 19:55:29

标签: python node.js string spell-checking

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

我正在尝试利用我们各自机器的内置实用程序来分析字符串的语法正确性。看来我不能只使用计算机上的内容,而可能必须下载要比较的字典。

我不确定是否有更好的方法可以做到这一点。我一直在尝试在本地做事,但我并不反对执行api或curl请求来确定字符串中的单词是否拼写正确。

我在看:

  • LanguageTool(您好wrold 无法返回错误)
  • Google的tbproxy似乎不起作用
  • 字典/ Meriam-Webster需要api键才能实现自动化。

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

有没有一种方法可以利用内置的机器词典,或者如果我下载字典/单词列表进行比较,那是理想的选择吗?

我认为最好使用单词表,但我不想重蹈覆辙。其他人做了什么来完成类似的任务?

2 个答案:

答案 0 :(得分:1)

您的问题被标记为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)使用内置拼写检查将使用操作系统规定的默认值,这可能不是您想要的。例如,所使用的语言可能由所选的OS语言决定。对于UI应用程序(例如,使用Electron构建),这可能很好,但是如果要使用OS语言以外的语言进行服务器端拼写检查,则可能会很困难。


在基本级别上,对某些文本进行拼写检查可以归结为:

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

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

有了这个,您就可以选择语言,不需要构建/下载任何本机代码,并且您的应用程序在每个平台上都可以相同地工作。如果您正在服务器上进行拼写检查,那么这可能是您最灵活的选择。

答案 1 :(得分: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);

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

误报将表示为:

  • 首字母缩写
  • 单词的非美国英语变体
  • 例如,无法识别的专有名词,星期几和月份。
  • 包含括号的字符串。可以通过将它们修剪成单词来扩充。

显然,这并非适用于所有情况,但是我添加了一个忽略此字符串函数,如果说它包含开发人员想要忽略的特殊单词或短语,则可以利用它。

这应作为节点脚本运行。