> [!NOTE] > 本文档由 WeHub 基于上游 README 翻译整理,属于社区翻译,非官方中文文档。 > [English](./README.en.md) · [原始项目](https://github.com/spencermountain/compromise) · [上游 README](https://github.com/spencermountain/compromise/blob/HEAD/README.md) > 原作者、版权与许可证归属以原始项目及本仓库 LICENSE 文件为准。
compromise
轻量自然语言处理
npm install compromise
Spencer Kelly 众多贡献者
法语德语意大利语西班牙语
你不觉得奇怪吗,
compromise 尽力将文本转换为数据。
它做出有限且合理的决策。
它并没有你想象的那么聪明。
```js import nlp from 'compromise' let doc = nlp('she sells seashells by the seashore.') doc.verbs().toPastTense() doc.text() // 'she sold seashells by the seashore.' ```
完全不必花哨:
```js if (doc.has('simon says #Verb')) { return true } ```
提取文本中的部分:
```js let doc = nlp(entireNovel) doc.match('the #Adjective of times').text() // "the blurst of times?" ```
match 文档
并获取数据: ```js import plg from 'compromise-speech' nlp.extend(plg) let doc = nlp('Milwaukee has certainly had its share of visitors..') doc.compute('syllables') doc.places().json() /* [{ "text": "Milwaukee", "terms": [{ "normal": "milwaukee", "syllables": ["mil", "wau", "kee"] }] }] */ ```
json 文档
避免脆弱解析器带来的问题: ```js let doc = nlp("we're not gonna take it..") doc.has('gonna') // true doc.has('going to') // true (implicit) // transform doc.contractions().expand() doc.text() // 'we are not going to take it..' ```
contraction 文档
并像操作数据一样随意摆弄内容: ```js let doc = nlp('ninety five thousand and fifty two') doc.numbers().add(20) doc.text() // 'ninety five thousand and seventy two' ```
number 文档
——因为它实际上就是数据—— ```js let doc = nlp('the purple dinosaur') doc.nouns().toPlural() doc.text() // 'the purple dinosaurs' ```
noun 文档
在客户端使用: ```html ``` 或者同样地: ```typescript import nlp from 'compromise' var doc = nlp('London is calling') doc.verbs().toNegative() // 'London is not calling' ``` compromise 约为 **~250kb**(minified):
它相当快,可在按键时运行:
它主要通过为基础词表做全部词形变化(conjugating all forms)来实现。 最终词库约为 ~14,000 words
你可以[在这里](https://observablehq.com/@spencermountain/compromise-internals). 了解更多工作原理——挺奇怪的。

好吧 —

compromise/one

对单词、句子和标点进行 tokenizer(分词器)。

```js import nlp from 'compromise/one' let doc = nlp("Wayne's World, party time") let data = doc.json() /* [{ normal:"wayne's world party time", terms:[{ text: "Wayne's", normal: "wayne" }, ... ] }] */ ```

tokenizer 文档
compromise/one 会把文本拆分,并封装为便捷的 API, /one 很快——大多数句子只需十分之一毫秒。 它每秒可处理 ~1mb 文本——相当于 10 个 Wikipedia 页面。 Infinite jest 需要 3 秒。
你也可以并行处理,或通过 compromise-speed 向其流式输入文本。

compromise/two

part-of-speech(词性)标注器与语法解释器。

```js import nlp from 'compromise/two' let doc = nlp("Wayne's World, party time") let str = doc.match('#Possessive #Noun').text() // "Wayne's World" ```

tagger 文档

compromise/two 会自动计算每个词的最基础语法。 这有时比人们意识到的更有用。 轻量语法有助于你编写更清晰的模板,并更接近信息本身。 compromise 拥有 83 tags,排列在 一张美观的图谱中。 #FirstName#Person#ProperNoun#Noun 运行 `doc.debug()` 即可查看每个词的语法 使用 `nlp.verbose('tagger')` 可查看每个标签的推理过程。 如果你更喜欢 Penn tags,可以这样派生: ```js let doc = nlp('welcome thrillho') doc.compute('penn') doc.json() ```

compromise/three

Phrase 与句子工具集。

```js import nlp from 'compromise/three' let doc = nlp("Wayne's World, party time") let str = doc.people().normalize().text() // "wayne" ```

selection 文档
compromise/three 是一套用于聚焦文本片段并进行操作的工具。 例如,`.numbers()` 会抓取文档中的所有数字,并通过 `.subtract()` 等方法进行扩展。 当你有一个短语或词组时,可用 `.json()` 查看其附加元数据 ```js let doc = nlp('four out of five dentists') console.log(doc.fractions().json()) /*[{ text: 'four out of five', terms: [ [Object], [Object], [Object], [Object] ], fraction: { numerator: 4, denominator: 5, decimal: 0.8 } } ]*/ ``` ```js let doc = nlp('$4.09CAD') doc.money().json() /*[{ text: '$4.09CAD', terms: [ [Object] ], number: { prefix: '$', num: 4.09, suffix: 'cad'} } ]*/ ``` ## API ### Compromise/one ##### 输出 - **[.text()](https://observablehq.com/@spencermountain/compromise-text)** - 以文本形式返回文档 - **[.json()](https://observablehq.com/@spencermountain/compromise-json)** - 以数据形式返回文档 - **[.debug()](https://observablehq.com/@spencermountain/compromise-output)** - 漂亮打印已解析的文档 - **[.out()](https://observablehq.com/@spencermountain/compromise-output)** - 具名或自定义输出 - **[.html({})](https://observablehq.com/@spencermountain/compromise-html)** - 为匹配项输出自定义 HTML 标签 - **[.wrap({})](https://observablehq.com/@spencermountain/compromise-output)** - 为文档匹配项生成自定义输出 ##### 工具 - **[.found](https://observablehq.com/@spencermountain/compromise-utils)** _[getter]_ - 该文档是否为空? - **[.docs](https://observablehq.com/@spencermountain/compromise-utils)** _[getter]_ 以 json 形式获取 term 对象 - **[.length](https://observablehq.com/@spencermountain/compromise-utils)** _[getter]_ - 统计文档中的字符数(字符串长度) - **[.isView](https://observablehq.com/@spencermountain/compromise-utils)** _[getter]_ - 识别 compromise 对象 - **[.compute()](https://observablehq.com/@spencermountain/compromise-compute)** - 对文档运行具名分析 - **[.clone()](https://observablehq.com/@spencermountain/compromise-utils)** - 深拷贝文档,使不留任何引用 - **[.termList()](https://observablehq.com/@spencermountain/compromise-accessors)** - 返回匹配中所有 Term 对象的扁平列表 - **[.cache({})](https://observablehq.com/@spencermountain/compromise-cache)** - 冻结文档当前状态,以提升速度 - **[.uncache()](https://observablehq.com/@spencermountain/compromise-cache)** - 解冻文档当前状态,以便可继续变换 - **[.freeze({})](https://observablehq.com/@spencermountain/compromise-freeze)** - 阻止这些 term 上的任何标签被移除 - **[.unfreeze({})](https://observablehq.com/@spencermountain/compromise-freeze)** - 恢复默认,允许标签再次变更 ##### 访问器(Accessors) - **[.all()](https://observablehq.com/@spencermountain/compromise-utils)** - 返回完整原始文档('zoom out') - **[.terms()](https://observablehq.com/@spencermountain/compromise-selections)** - 按每个单独词项拆分结果 - **[.first(n)](https://observablehq.com/@spencermountain/compromise-accessors)** - 仅使用第一个(前几个)结果 - **[.last(n)](https://observablehq.com/@spencermountain/compromise-accessors)** - 仅使用最后一个(后几个)结果 - **[.slice(n,n)](https://observablehq.com/@spencermountain/compromise-accessors)** - 获取结果的子集 - **[.eq(n)](https://observablehq.com/@spencermountain/compromise-accessors)** - 仅使用第 n 个结果 - **[.firstTerms()](https://observablehq.com/@spencermountain/compromise-accessors)** - 获取每个匹配中的第一个词 - **[.lastTerms()](https://observablehq.com/@spencermountain/compromise-accessors)** - 获取每个匹配中的最后一个词 - **[.fullSentences()](https://observablehq.com/@spencermountain/compromise-accessors)** - 获取每个匹配所在的完整句子 - **[.groups()](https://observablehq.com/@spencermountain/compromise-accessors)** - 从匹配中提取所有命名捕获组(named capture-groups) - **[.wordCount()](https://observablehq.com/@spencermountain/compromise-utils)** - 统计文档中的词项数量 - **[.confidence()](https://observablehq.com/@spencermountain/compromise-utils)** - 词性标注(POS tag)解释的平均置信度分数 ##### 匹配(Match) _(匹配方法使用 [match-syntax](https://docs.compromise.cool/compromise-match-syntax).)_ - **[.match('')](https://observablehq.com/@spencermountain/compromise-match)** - 返回一个新的 Doc,并以当前文档作为父文档 - **[.not('')](https://observablehq.com/@spencermountain/compromise-match)** - 返回除此匹配外的所有结果 - **[.matchOne('')](https://observablehq.com/@spencermountain/compromise-match)** - 仅返回第一个匹配 - **[.if('')](https://observablehq.com/@spencermountain/compromise-match)** - 仅当当前短语包含此匹配时才返回该短语('only') - **[.ifNo('')](https://observablehq.com/@spencermountain/compromise-match)** - 过滤掉包含此匹配的所有当前短语('notIf') - **[.has('')](https://observablehq.com/@spencermountain/compromise-match)** - 若存在此匹配则返回布尔值 - **[.before('')](https://observablehq.com/@spencermountain/compromise-match)** - 返回每个短语中匹配之前的所有词项 - **[.after('')](https://observablehq.com/@spencermountain/compromise-match)** - 返回每个短语中匹配之后的所有词项 - **[.union()](https://observablehq.com/@spencermountain/compromise-set)** - 返回合并后的匹配,不含重复项 - **[.intersection()](https://observablehq.com/@spencermountain/compromise-set)** - 仅返回重复的匹配 - **[.complement()](https://observablehq.com/@spencermountain/compromise-set)** - 获取不在另一匹配中的所有内容 - **[.settle()](https://observablehq.com/@spencermountain/compromise-set)** - 从匹配中移除重叠部分 - **[.growRight('')](https://observablehq.com/@spencermountain/compromise-match)** - 在每个匹配之后立即添加任何匹配的词项 - **[.growLeft('')](https://observablehq.com/@spencermountain/compromise-match)** - 在每个匹配之前立即添加任何匹配的词项 - **[.grow('')](https://observablehq.com/@spencermountain/compromise-match)** - 在每个匹配之前或之后添加任何匹配的词项 - **[.sweep(net)](https://observablehq.com/@spencermountain/compromise-sweep)** - 将一系列匹配对象应用于文档 - **[.splitOn('')](https://observablehq.com/@spencermountain/compromise-split)** - 为每个匹配返回包含三部分的 Document('splitOn') - **[.splitBefore('')](https://observablehq.com/@spencermountain/compromise-split)** - 在每个匹配片段之前分割短语 - **[.splitAfter('')](https://observablehq.com/@spencermountain/compromise-split)** - 在每个匹配片段之后分割短语 - **[.join()](https://observablehq.com/@spencermountain/compromise-split)** - 合并每个匹配中所有相邻的词项 - **[.joinIf(leftMatch, rightMatch)](https://observablehq.com/@spencermountain/compromise-split)** - 在给定条件下合并相邻词项 - **[.lookup([])](https://observablehq.com/@spencermountain/compromise-match)** - 快速查找字符串匹配数组 - **[.autoFill()](https://observablehq.com/@spencermountain/compromise-typeahead)** - 在文档上创建自动补全(type-ahead)假设 ##### 标注(Tag) - **[.tag('')](https://observablehq.com/@spencermountain/compromise-tagger)** - 为所有词项赋予给定标签 - **[.tagSafe('')](https://observablehq.com/@spencermountain/compromise-tagger)** - 仅当与当前标签一致时才将标签应用于词项 - **[.unTag('')](https://observablehq.com/@spencermountain/compromise-tagger)** - 从给定词项中移除此词项 - **[.canBe('')](https://observablehq.com/@spencermountain/compromise-tagger)** - 仅返回可以具有此标签的词项 ##### 大小写(Case) - **[.toLowerCase()](https://observablehq.com/@spencermountain/compromise-case)** - 将每个词项的每个字母转为小写 - **[.toUpperCase()](https://observablehq.com/@spencermountain/compromise-case)** - 将每个词项的每个字母转为大写 - **[.toTitleCase()](https://observablehq.com/@spencermountain/compromise-case)** - 将每个词项的首字母大写 - **[.toCamelCase()](https://observablehq.com/@spencermountain/compromise-case)** - 移除空白并将每个词项转为标题大小写(title-case) ##### 空白(Whitespace) - **[.pre('')](https://observablehq.com/@spencermountain/compromise-whitespace)** - 在每个匹配之前添加此标点或空白 - **[.post('')](https://observablehq.com/@spencermountain/compromise-whitespace)** - 在每个匹配之后添加此标点或空白 - **[.trim()](https://observablehq.com/@spencermountain/compromise-whitespace)** - 移除首尾空白 - **[.hyphenate()](https://observablehq.com/@spencermountain/compromise-whitespace)** - 用连字符连接单词并移除空白 - **[.dehyphenate()](https://observablehq.com/@spencermountain/compromise-whitespace)** - 移除单词之间的连字符并设置空白 - **[.toQuotations()](https://observablehq.com/@spencermountain/compromise-whitespace)** - 在这些匹配周围添加引号 - **[.toParentheses()](https://observablehq.com/@spencermountain/compromise-whitespace)** - 在这些匹配周围添加括号 ##### 循环(Loops) - **[.map(fn)](https://observablehq.com/@spencermountain/compromise-loops)** - 对每个短语运行函数并创建新文档 - **[.forEach(fn)](https://observablehq.com/@spencermountain/compromise-loops)** - 将每个短语作为独立文档对其运行函数 - **[.filter(fn)](https://observablehq.com/@spencermountain/compromise-loops)** - 仅返回结果为 true 的短语 - **[.find(fn)](https://observablehq.com/@spencermountain/compromise-loops)** - 返回仅包含第一个匹配短语的文档 - **[.some(fn)](https://observablehq.com/@spencermountain/compromise-loops)** - 若存在一个匹配短语则返回 true 或 false - **[.random(fn)](https://observablehq.com/@spencermountain/compromise-loops)** - 对结果子集进行抽样 ##### 插入(Insert) - **[.replace(match, replace)](https://observablehq.com/@spencermountain/compromise-insert)** - 搜索并用新内容替换匹配 - **[.replaceWith(replace)](https://observablehq.com/@spencermountain/compromise-insert)** - 替换为新文本 - **[.remove()](https://observablehq.com/@spencermountain/compromise-insert)** - 从文档中完全移除这些词项 - **[.insertBefore(str)](https://observablehq.com/@spencermountain/compromise-insert)** - 将这些新词项添加到每个匹配的前面(prepend) - **[.insertAfter(str)](https://observablehq.com/@spencermountain/compromise-insert)** - 将这些新词项添加到每个匹配的末尾(append) - **[.concat()](https://observablehq.com/@spencermountain/compromise-insert)** - 将这些新内容添加到末尾 - **[.swap(fromLemma, toLemma)](https://observablehq.com/@spencermountain/compromise-root)** - 智能替换词根,并使用正确的词形变化 ##### Transform - **[.sort('method')](https://observablehq.com/@spencermountain/compromise-sorting)** - 原地重新排列匹配项的顺序 - **[.reverse()](https://observablehq.com/@spencermountain/compromise-sorting)** - 反转匹配项的顺序,但不反转词语 - **[.unique()](https://observablehq.com/@spencermountain/compromise-sorting)** - 移除所有重复的匹配项 ##### Lib _(这些方法位于主 `nlp` 对象上)_ - **[nlp.tokenize(str)](https://observablehq.com/@spencermountain/compromise-tokenization)** - 解析文本,但不进行词性标注(POS-tagging) - **[nlp.lazy(str, match)](https://observablehq.com/@spencermountain/compromise-performance)** - 以最小分析量扫描文本 - **[nlp.plugin({})](https://observablehq.com/@spencermountain/compromise-constructor-methods)** - 混入 compromise-plugin - **[nlp.parseMatch(str)](https://observablehq.com/@spencermountain/compromise-constructor-methods)** - 预先将匹配语句解析为 json - **[nlp.world()](https://observablehq.com/@spencermountain/compromise-constructor-methods)** - 获取或修改库内部结构 - **[nlp.model()](https://observablehq.com/@spencermountain/compromise-constructor-methods)** - 获取所有当前语言数据 - **[nlp.methods()](https://observablehq.com/@spencermountain/compromise-constructor-methods)** - 获取或修改内部方法 - **[nlp.hooks()](https://observablehq.com/@spencermountain/compromise-constructor-methods)** - 查看哪些计算方法会自动运行 - **[nlp.verbose(mode)](https://observablehq.com/@spencermountain/compromise-constructor-methods)** - 记录决策过程以便调试 - **[nlp.version](https://observablehq.com/@spencermountain/compromise-constructor-methods)** - 库的当前 semver 版本 - **[nlp.addWords(obj, isFrozen?)](https://observablehq.com/@spencermountain/compromise-plugin)** - 向词表添加新词 - **[nlp.addTags(obj)](https://observablehq.com/@spencermountain/compromise-plugin)** - 向 tagSet 添加新标签 - **[nlp.typeahead(arr)](https://observablehq.com/@spencermountain/compromise-typeahead)** - 向自动填充词典添加词语 - **[nlp.buildTrie(arr)](https://observablehq.com/@spencermountain/compromise-lookup)** - 将词列表编译为快速查找形式 - **[nlp.buildNet(arr)](https://observablehq.com/@spencermountain/compromise-sweep)** - 将匹配列表编译为快速匹配形式 ### compromise/two: ##### Contractions - **[.contractions()](https://observablehq.com/@spencermountain/compromise-contractions)** - 如 "didn't" 这类缩略形式 - **[.contractions().expand()](https://observablehq.com/@spencermountain/compromise-contractions)** - 如 "didn't" 这类缩略形式 - **[.contract()](https://observablehq.com/@spencermountain/compromise-contractions)** - 如 "didn't" 这类缩略形式 ### compromise/three: - **[.normalize({})](https://observablehq.com/@spencermountain/compromise-normalization)** - 以各种方式清理文本 ##### Nouns - **[.nouns()](https://observablehq.com/@spencermountain/nouns)** - 返回后续被标注为 Noun 的词语 - **[.nouns().json()](https://observablehq.com/@spencermountain/nouns)** - 附带名词元数据的增强输出 - **[.nouns().parse()](https://observablehq.com/@spencermountain/nouns)** - 获取分词后的名词短语 - **[.nouns().isPlural()](https://observablehq.com/@spencermountain/nouns)** - 仅返回复数名词 - **[.nouns().isSingular()](https://observablehq.com/@spencermountain/nouns)** - 仅返回单数名词 - **[.nouns().toPlural()](https://observablehq.com/@spencermountain/nouns)** - `'football captain' → 'football captains'` - **[.nouns().toSingular()](https://observablehq.com/@spencermountain/nouns)** - `'turnovers' → 'turnover'` - **[.nouns().adjectives()](https://observablehq.com/@spencermountain/nouns)** - 获取描述该名词的形容词 ##### Verbs - **[.verbs()](https://observablehq.com/@spencermountain/verbs)** - 返回后续被标注为 Verb 的词语 - **[.verbs().json()](https://observablehq.com/@spencermountain/verbs)** - 附带动词元数据的增强输出 - **[.verbs().parse()](https://observablehq.com/@spencermountain/verbs)** - 获取分词后的动词短语 - **[.verbs().subjects()](https://observablehq.com/@spencermountain/verbs)** - 执行该动词动作的主体 - **[.verbs().adverbs()](https://observablehq.com/@spencermountain/verbs)** - 返回描述该动词的副词 - **[.verbs().isSingular()](https://observablehq.com/@spencermountain/verbs)** - 返回单数动词,如 'spencer walks' - **[.verbs().isPlural()](https://observablehq.com/@spencermountain/verbs)** - 返回复数动词,如 'we walk' - **[.verbs().isImperative()](https://observablehq.com/@spencermountain/verbs)** - 仅返回祈使动词,如 'eat it!' - **[.verbs().toPastTense()](https://observablehq.com/@spencermountain/verbs)** - `'will go' → 'went'` - **[.verbs().toPresentTense()](https://observablehq.com/@spencermountain/verbs)** - `'walked' → 'walks'` - **[.verbs().toFutureTense()](https://observablehq.com/@spencermountain/verbs)** - `'walked' → 'will walk'` - **[.verbs().toInfinitive()](https://observablehq.com/@spencermountain/verbs)** - `'walks' → 'walk'` - **[.verbs().toGerund()](https://observablehq.com/@spencermountain/verbs)** - `'walks' → 'walking'` - **[.verbs().toPastParticiple()](https://observablehq.com/@spencermountain/verbs)** - `'drive' → 'had driven'` - **[.verbs().conjugate()](https://observablehq.com/@spencermountain/verbs)** - 返回这些动词的所有变位形式 - **[.verbs().isNegative()](https://observablehq.com/@spencermountain/verbs)** - 返回含 'not'、'never' 或 'no' 的动词 - **[.verbs().isPositive()](https://observablehq.com/@spencermountain/verbs)** - 仅返回不含 'not'、'never' 或 'no' 的动词 - **[.verbs().toNegative()](https://observablehq.com/@spencermountain/verbs)** - `'went' → 'did not go'` - **[.verbs().toPositive()](https://observablehq.com/@spencermountain/verbs)** - `"didn't study" → 'studied'` ##### Numbers - **[.numbers()](https://observablehq.com/@spencermountain/compromise-values)** - 获取所有文字形式和数值形式的数字 - **[.numbers().parse()](https://observablehq.com/@spencermountain/compromise-values)** - 获取分词后的数字短语 - **[.numbers().get()](https://observablehq.com/@spencermountain/compromise-values)** - 获取简单的 JavaScript 数字 - **[.numbers().json()](https://observablehq.com/@spencermountain/compromise-values)** - 附带数字元数据的增强输出 - **[.numbers().toNumber()](https://observablehq.com/@spencermountain/compromise-values)** - 将 'five' 转换为 `5` - **[.numbers().toLocaleString()](https://observablehq.com/@spencermountain/compromise-values)** - 为数字添加逗号或更美观的格式 - **[.numbers().toText()](https://observablehq.com/@spencermountain/compromise-values)** - 将 '5' 转换为 `five` - **[.numbers().toOrdinal()](https://observablehq.com/@spencermountain/compromise-values)** - 将 'five' 转换为 `fifth` 或 `5th` - **[.numbers().toCardinal()](https://observablehq.com/@spencermountain/compromise-values)** - 将 'fifth' 转换为 `five` 或 `5` - **[.numbers().isOrdinal()](https://observablehq.com/@spencermountain/compromise-values)** - 仅返回序数 - **[.numbers().isCardinal()](https://observablehq.com/@spencermountain/compromise-values)** - 仅返回基数 - **[.numbers().isEqual(n)](https://observablehq.com/@spencermountain/compromise-values)** - 返回等于该值的数字 - **[.numbers().greaterThan(min)](https://observablehq.com/@spencermountain/compromise-values)** - 返回大于 n 的数字 - **[.numbers().lessThan(max)](https://observablehq.com/@spencermountain/compromise-values)** - 返回小于 n 的数字 - **[.numbers().between(min, max)](https://observablehq.com/@spencermountain/compromise-values)** - 返回 min 与 max 之间的数字 - **[.numbers().isUnit(unit)](https://observablehq.com/@spencermountain/compromise-values)** - 仅返回指定单位的数字,如 'km' - **[.numbers().set(n)](https://observablehq.com/@spencermountain/compromise-values)** - 将数字设为 n - **[.numbers().add(n)](https://observablehq.com/@spencermountain/compromise-values)** - 将数字增加 n - **[.numbers().subtract(n)](https://observablehq.com/@spencermountain/compromise-values)** - 将数字减少 n - **[.numbers().increment()](https://observablehq.com/@spencermountain/compromise-values)** - 将数字加 1 - **[.numbers().decrement()](https://observablehq.com/@spencermountain/compromise-values)** - 将数字减 1 - **[.money()](https://observablehq.com/@spencermountain/compromise-values)** - 如 `'$2.50'` 这类金额 - **[.money().get()](https://observablehq.com/@spencermountain/compromise-values)** - 获取解析后的金额 - **[.money().json()](https://observablehq.com/@spencermountain/compromise-values)** - 货币与数字信息 - **[.money().currency()](https://observablehq.com/@spencermountain/compromise-values)** - 金额所使用的货币 - **[.fractions()](https://observablehq.com/@spencermountain/compromise-values)** - 如 '2/3rds' 或 'one out of five' - **[.fractions().parse()](https://observablehq.com/@spencermountain/compromise-values)** - 获取分词后的分数 - **[.fractions().get()](https://observablehq.com/@spencermountain/compromise-values)** - 简单的分子、分母数据 - **[.fractions().json()](https://observablehq.com/@spencermountain/compromise-values)** - 附带分数数据的增强 json 输出 - **[.fractions().toDecimal()](https://observablehq.com/@spencermountain/compromise-values)** - '2/3' -> '0.66' - **[.fractions().normalize()](https://observablehq.com/@spencermountain/compromise-values)** - 'four out of 10' -> '4/10' - **[.fractions().toText()](https://observablehq.com/@spencermountain/compromise-values)** - '4/10' -> 'four tenths' - **[.fractions().toPercentage()](https://observablehq.com/@spencermountain/compromise-values)** - '4/10' -> '40%' - **[.percentages()](https://observablehq.com/@spencermountain/compromise-values)** - 如 '2.5%' - **[.percentages().get()](https://observablehq.com/@spencermountain/compromise-values)** - 返回百分比数值除以 100 - **[.percentages().json()](https://observablehq.com/@spencermountain/compromise-values)** - 附带百分比信息的增强 json 输出 - **[.percentages().toFraction()](https://observablehq.com/@spencermountain/compromise-values)** - '80%' -> '8/10' ##### 句子 - **[.sentences()](https://observablehq.com/@spencermountain/compromise-sentences)** - 返回带有附加方法的句子类 - **[.sentences().json()](https://observablehq.com/@spencermountain/compromise-sentences)** - 附带句子元数据的增强输出 - **[.sentences().toPastTense()](https://observablehq.com/@spencermountain/compromise-sentences)** - `he walks` -> `he walked` - **[.sentences().toPresentTense()](https://observablehq.com/@spencermountain/compromise-sentences)** - `he walked` -> `he walks` - **[.sentences().toFutureTense()](https://observablehq.com/@spencermountain/compromise-sentences)** -- `he walks` -> `he will walk` - **[.sentences().toInfinitive()](https://observablehq.com/@spencermountain/compromise-sentences)** -- verb root-form `he walks` -> `he walk` - **[.sentences().toNegative()](https://observablehq.com/@spencermountain/compromise-sentences)** - - `he walks` -> `he didn't walk` - **[.sentences().isQuestion()](https://observablehq.com/@spencermountain/compromise-sentences)** - 返回带 `?` 的疑问句 - **[.sentences().isExclamation()](https://observablehq.com/@spencermountain/compromise-sentences)** - 返回带 `!` 的感叹句 - **[.sentences().isStatement()](https://observablehq.com/@spencermountain/compromise-sentences)** - 返回不含 `?` 或 `!` 的陈述句 ##### 形容词 - **[.adjectives()](https://observablehq.com/@spencermountain/compromise-selections)** - 诸如 `'quick'` 之类的词 - **[.adjectives().json()](https://observablehq.com/@spencermountain/compromise-selections)** - 获取形容词元数据 - **[.adjectives().conjugate()](https://observablehq.com/@spencermountain/compromise-selections)** - 返回这些形容词的所有词形变化 - **[.adjectives().adverbs()](https://observablehq.com/@spencermountain/compromise-selections)** - 获取描述该形容词的副词 - **[.adjectives().toComparative()](https://observablehq.com/@spencermountain/compromise-selections)** - 'quick' -> 'quicker' - **[.adjectives().toSuperlative()](https://observablehq.com/@spencermountain/compromise-selections)** - 'quick' -> 'quickest' - **[.adjectives().toAdverb()](https://observablehq.com/@spencermountain/compromise-selections)** - 'quick' -> 'quickly' - **[.adjectives().toNoun()](https://observablehq.com/@spencermountain/compromise-selections)** - 'quick' -> 'quickness' ##### 其他选择项 - **[.clauses()](https://observablehq.com/@spencermountain/compromise-selections)** - 将句子拆分为多词短语 - **[.chunks()](https://observablehq.com/@spencermountain/compromise-selections)** - 将句子拆分为名词短语和动词短语 - **[.hyphenated()](https://observablehq.com/@spencermountain/compromise-selections)** - 所有以连字符或破折号连接的词项,例如 `'wash-out'` - **[.phoneNumbers()](https://observablehq.com/@spencermountain/compromise-selections)** - 诸如 `'(939) 555-0113'` 之类的内容 - **[.hashTags()](https://observablehq.com/@spencermountain/compromise-selections)** - 诸如 `'#nlp'` 之类的内容 - **[.emails()](https://observablehq.com/@spencermountain/compromise-selections)** - 诸如 `'hi@compromise.cool'` 之类的内容 - **[.emoticons()](https://observablehq.com/@spencermountain/compromise-selections)** - 诸如 `:)` 之类的内容 - **[.emojis()](https://observablehq.com/@spencermountain/compromise-selections)** - 诸如 `💋` 之类的内容 - **[.atMentions()](https://observablehq.com/@spencermountain/compromise-selections)** - 诸如 `'@nlp_compromise'` 之类的内容 - **[.urls()](https://observablehq.com/@spencermountain/compromise-selections)** - 诸如 `'compromise.cool'` 之类的内容 - **[.pronouns()](https://observablehq.com/@spencermountain/compromise-selections)** - 诸如 `'he'` 之类的内容 - **[.conjunctions()](https://observablehq.com/@spencermountain/compromise-selections)** - 诸如 `'but'` 之类的内容 - **[.prepositions()](https://observablehq.com/@spencermountain/compromise-selections)** - 诸如 `'of'` 之类的内容 - **[.abbreviations()](https://observablehq.com/@spencermountain/compromise-selections)** - 诸如 `'Mrs.'` 之类的内容 - **[.people()](https://observablehq.com/@spencermountain/topics-named-entity-recognition)** - 诸如 'John F. Kennedy' 之类的姓名 - **[.people().json()](https://observablehq.com/@spencermountain/topics-named-entity-recognition)** - 获取人名元数据 - **[.people().parse()](https://observablehq.com/@spencermountain/topics-named-entity-recognition)** - 获取人名解析结果 - **[.places()](https://observablehq.com/@spencermountain/topics-named-entity-recognition)** - 例如 'Paris, France' - **[.organizations()](https://observablehq.com/@spencermountain/topics-named-entity-recognition)** - 例如 'Google, Inc' - **[.topics()](https://observablehq.com/@spencermountain/topics-named-entity-recognition)** - `people()` + `places()` + `organizations()` - **[.adverbs()](https://observablehq.com/@spencermountain/compromise-selections)** - 诸如 `'quickly'` 之类的词 - **[.adverbs().json()](https://observablehq.com/@spencermountain/compromise-selections)** - 获取副词元数据 - **[.acronyms()](https://observablehq.com/@spencermountain/compromise-selections)** - 诸如 `'FBI'` 之类的内容 - **[.acronyms().strip()](https://observablehq.com/@spencermountain/compromise-selections)** - 移除缩写词中的句点 - **[.acronyms().addPeriods()](https://observablehq.com/@spencermountain/compromise-selections)** - 为缩写词添加句点 - **[.parentheses()](https://observablehq.com/@spencermountain/compromise-selections)** - 返回括号内的任何内容 - **[.parentheses().strip()](https://observablehq.com/@spencermountain/compromise-selections)** - 移除括号 - **[.possessives()](https://observablehq.com/@spencermountain/compromise-selections)** - 诸如 `"Spencer's"` 之类的内容 - **[.possessives().strip()](https://observablehq.com/@spencermountain/compromise-selections)** - "Spencer's" -> "Spencer" - **[.quotations()](https://observablehq.com/@spencermountain/compromise-selections)** - 返回成对引号内的任何词项 - **[.quotations().strip()](https://observablehq.com/@spencermountain/compromise-selections)** - 移除引号 - **[.slashes()](https://observablehq.com/@spencermountain/compromise-selections)** - 返回以斜杠分组的任何词项 - **[.slashes().split()](https://observablehq.com/@spencermountain/compromise-selections)** - 将 'love/hate' 转换为 'love hate'

### .extend(): 本库内置了一套体贴且符合常识的英语语法基线。 你可以随意修改,甚至彻底推翻任何设置——这其实也是乐趣所在。 最简单的做法是为任意给定词语建议标签: ```js let myWords = { kermit: 'FirstName', fozzie: 'FirstName', } let doc = nlp(muppetText, myWords) ``` 或者通过 [compromise-plugin](https://observablehq.com/@spencermountain/compromise-plugins). 进行更大幅度的修改 ```js import nlp from 'compromise' nlp.extend({ // add new tags tags: { Character: { isA: 'Person', notA: 'Adjective', }, }, // add or change words in the lexicon words: { kermit: 'Character', gonzo: 'Character', }, // change inflections irregulars: { get: { pastTense: 'gotten', gerund: 'gettin', }, }, // add new methods to compromise api: View => { View.prototype.kermitVoice = function () { this.sentences().prepend('well,') this.match('i [(am|was)]').prepend('um,') return this } }, }) ```
.plugin() 文档
### 文档: ##### 入门导读: - **[#1) 输入 → 输出](https://docs.compromise.cool/tutorial-1)** - **[#2) 匹配与转换](https://docs.compromise.cool/compromise-tutorial-2)** - **[#3) 制作聊天机器人](https://docs.compromise.cool/compromise-making-a-bot)**
##### 文档: | 概念 | API | 插件 | | ------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------: | -------------------------------------------------------------------------------------: | | [准确度 (Accuracy)](https://observablehq.com/@spencermountain/compromise-accuracy) | [Accessors](https://observablehq.com/@spencermountain/compromise-accessors) | [Adjectives](https://observablehq.com/@spencermountain/compromise-adjectives) | | [缓存 (Caching)](https://observablehq.com/@spencermountain/compromise-cache) | [Constructor-methods](https://observablehq.com/@spencermountain/compromise-constructor-methods) | [Dates](https://observablehq.com/@spencermountain/compromise-dates) | | [大小写 (Case)](https://observablehq.com/@spencermountain/compromise-case) | [Contractions](https://observablehq.com/@spencermountain/compromise-contractions) | [Export](https://observablehq.com/@spencermountain/compromise-export) | | [文件大小 (Filesize)](https://observablehq.com/@spencermountain/compromise-filesize) | [Insert](https://observablehq.com/@spencermountain/compromise-insert) | [Hash](https://observablehq.com/@spencermountain/compromise-hash) | | [内部机制 (Internals)](https://observablehq.com/@spencermountain/compromise-internals) | [Json](https://observablehq.com/@spencermountain/compromise-json) | [Html](https://observablehq.com/@spencermountain/compromise-html) | | [对齐 (Justification)](https://observablehq.com/@spencermountain/compromise-justification) | [Character Offsets](https://observablehq.com/@spencermountain/compromise-offsets) | [Keypress](https://observablehq.com/@spencermountain/compromise-keypress) | | [词典 (Lexicon)](https://observablehq.com/@spencermountain/compromise-lexicon) | [Loops](https://observablehq.com/@spencermountain/compromise-loops) | [Ngrams](https://observablehq.com/@spencermountain/compromise-ngram) | | [匹配语法 (Match-syntax)](https://observablehq.com/@spencermountain/compromise-match-syntax) | [Match](https://observablehq.com/@spencermountain/compromise-match) | [Numbers](https://observablehq.com/@spencermountain/compromise-values) | | [性能 (Performance)](https://observablehq.com/@spencermountain/compromise-performance) | [Nouns](https://observablehq.com/@spencermountain/nouns) | [Paragraphs](https://observablehq.com/@spencermountain/compromise-paragraphs) | | [插件 (Plugins)](https://observablehq.com/@spencermountain/compromise-plugins) | [Output](https://observablehq.com/@spencermountain/compromise-output) | [Scan](https://observablehq.com/@spencermountain/compromise-scan) | | [项目 (Projects)](https://observablehq.com/@spencermountain/compromise-projects) | [Selections](https://observablehq.com/@spencermountain/compromise-selections) | [Sentences](https://observablehq.com/@spencermountain/compromise-sentences) | | [标注器 (Tagger)](https://observablehq.com/@spencermountain/compromise-tagger) | [Sorting](https://observablehq.com/@spencermountain/compromise-sorting) | [Syllables](https://observablehq.com/@spencermountain/compromise-syllables) | | [标签 (Tags)](https://observablehq.com/@spencermountain/compromise-tags) | [Split](https://observablehq.com/@spencermountain/compromise-split) | [Pronounce](https://observablehq.com/@spencermountain/compromise-pronounce) | | [分词 (Tokenization)](https://observablehq.com/@spencermountain/compromise-tokenization) | [Text](https://observablehq.com/@spencermountain/compromise-text) | [Strict](https://observablehq.com/@spencermountain/compromise-strict) | | [命名实体 (Named-Entities)](https://observablehq.com/@spencermountain/topics-named-entity-recognition) | [Utils](https://observablehq.com/@spencermountain/compromise-utils) | [Penn-tags](https://observablehq.com/@spencermountain/compromise-penn-tags) | | [空白字符 (Whitespace)](https://observablehq.com/@spencermountain/compromise-whitespace) | [Verbs](https://observablehq.com/@spencermountain/verbs) | [Typeahead](https://observablehq.com/@spencermountain/compromise/compromise-typeahead) | | [世界数据 (World data)](https://observablehq.com/@spencermountain/compromise-world) | [Normalization](https://observablehq.com/@spencermountain/compromise-normalization) | [Sweep](https://observablehq.com/@spencermountain/compromise-sweep) | | [模糊匹配 (Fuzzy-matching)](https://observablehq.com/@spencermountain/compromise-fuzzy-matching) | [Typescript](https://observablehq.com/@spencermountain/compromise-typescript) | [Mutation](https://observablehq.com/@spencermountain/compromise-mutation) | | [词根形式 (Root-forms)](https://observablehq.com/@spencermountain/compromise-root) |
##### 演讲: - **[语言即界面 (Language as an Interface)](https://www.youtube.com/watch?v=WuPVS2tCg8s)** - 作者 Spencer Kelly - **[编写聊天机器人 (Coding Chat Bots)](https://www.youtube.com/watch?v=c_hmwFwvO0U)** - 作者 KahWee Teng - **[关于打字与数据 (On Typing and data)](https://vimeo.com/496095722)** - 作者 Spencer Kelly ##### 文章: - **[使用 NLP 与 JavaScript 对社交对话进行地理编码](http://compromise.cool)** - 作者 Microsoft - **[微服务配方 (Microservice Recipe)](https://eventn.com/recipes/text-parsing-with-nlp-compromise)** - 作者 Eventn - **[使用 Compromise 解析冒险游戏句子](https://killalldefects.com/2020/02/20/adventure-game-sentence-parsing-with-compromise/)** - **[构建基于文本的游戏 (Building Text-Based Games)](https://killalldefects.com/2019/09/24/building-text-based-games-with-compromise-nlp/)** - 作者 Matt Eland - **[BigQuery 中的 JavaScript 乐趣](https://medium.com/@hoffa/new-in-bigquery-persistent-udfs-c9ea4100fd83#6e09)** - 作者 Felipe Hoffa - **[自然语言处理……在浏览器中?](https://dev.to/charlesdlandau/natural-language-processing-in-the-browser-52hj)** - 作者 Charles Landau ##### 一些有趣的应用: - **[自动化 Bechdel 测试 (Automated Bechdel Test)](https://github.com/guardian/bechdel-test)** - 作者 The Guardian - **[故事生成框架 (Story generation framework)](https://perchance.org/welcome)** - 作者 Jose Phrocca - **[列表 Tumblr 博客 (Tumbler blog of lists)](https://leanstooneside.tumblr.com/)** - 类似 horse-ebooks 的列表 - 作者 Michael Paulukonis - **[基于转录文本的视频编辑 (Video Editing from Transcription)](https://newtheory.io/)** - 作者 New Theory - **[浏览器扩展事实核查 (Browser extension Fact-checking)](https://github.com/AlexanderKidd/FactoidL)** - 作者 Alexander Kidd - **[Siri 快捷指令 (Siri shortcut)](https://routinehub.co/shortcut/3260)** - 作者 Michael Byrns - **[Amazon Skill](https://github.com/tajddin/voiceplay)** - 作者 Tajddin Maghni - **[任务型 Slack 机器人 (Tasking Slack-bot)](https://github.com/kevinsuh/toki)** - 作者 Kevin Suh [[查看更多]](https://observablehq.com/@spencermountain/compromise-projects) ##### 对比 - [Compromise 与 Spacy](https://observablehq.com/@spencermountain/compromise-and-spacy) - [Compromise 与 NLTK](https://observablehq.com/@spencermountain/compromise-and-nltk)

### 插件: 以下是一些实用的扩展: ##### 日期 `npm install compromise-dates` - **[.dates()](https://observablehq.com/@spencermountain/compromise-dates)** - 查找诸如 `June 8th` 或 `03/03/18` 的日期 - **[.dates().get()](https://observablehq.com/@spencermountain/compromise-dates)** - 返回简单的起止 JSON 结果 - **[.dates().json()](https://observablehq.com/@spencermountain/compromise-dates)** - 带日期元数据的富输出 - **[.dates().format('')](https://observablehq.com/@spencermountain/compromise-dates)** - 将日期转换为指定格式 - **[.dates().toShortForm()](https://observablehq.com/@spencermountain/compromise-dates)** - 将 'Wednesday' 转为 'Wed' 等 - **[.dates().toLongForm()](https://observablehq.com/@spencermountain/compromise-dates)** - 将 'Feb' 转为 'February' 等 - **[.durations()](https://observablehq.com/@spencermountain/compromise-dates)** - `2 weeks` 或 `5mins` - **[.durations().get()](https://observablehq.com/@spencermountain/compromise-dates)** - 返回时长的简单 JSON - **[.durations().json()](https://observablehq.com/@spencermountain/compromise-dates)** - 带时长元数据的富输出 - **[.times()](https://observablehq.com/@spencermountain/compromise-dates)** - `4:30pm` 或 `half past five` - **[.times().get()](https://observablehq.com/@spencermountain/compromise-dates)** - 返回时间的简单 JSON - **[.times().json()](https://observablehq.com/@spencermountain/compromise-dates)** - 带时间元数据的富输出 ##### 统计 `npm install compromise-stats` - **[.tfidf({})](https://observablehq.com/@spencermountain/compromise-tfidf)** - 按词频与独特性对词语排序 - **[.ngrams({})](https://observablehq.com/@spencermountain/compromise-ngram)** - 按词数列出所有重复的子短语 - **[.unigrams()](https://observablehq.com/@spencermountain/compromise-ngram)** - 一词 n-gram - **[.bigrams()](https://observablehq.com/@spencermountain/compromise-ngram)** - 两词 n-gram - **[.trigrams()](https://observablehq.com/@spencermountain/compromise-ngram)** - 三词 n-gram - **[.startgrams()](https://observablehq.com/@spencermountain/compromise-ngram)** - 包含短语首词的 n-gram - **[.endgrams()](https://observablehq.com/@spencermountain/compromise-ngram)** - 包含短语末词的 n-gram - **[.edgegrams()](https://observablehq.com/@spencermountain/compromise-ngram)** - 包含短语首词或末词的 n-gram ##### 语音 `npm install compromise-syllables` - **[.syllables()](https://observablehq.com/@spencermountain/compromise-syllables)** - 按典型发音拆分每个词 - **[.soundsLike()](https://observablehq.com/@spencermountain/compromise-soundsLike)** - 生成估计的发音 ##### Wikipedia `npm install compromise-wikipedia` - **[.wikipedia()](https://observablehq.com/@spencermountain/compromise-wikipedia)** - 压缩版文章对齐

### Typescript 我们致力于支持 TypeScript/Deno,主库与官方插件均提供支持: ```ts import nlp from 'compromise' import stats from 'compromise-stats' const nlpEx = nlp.extend(stats) nlpEx('This is type safe!').ngrams({ min: 1 }) ```
TypeScript 文档
#### 局限性: - **slash-support:** 我们目前会像处理连字符一样,将斜杠拆成不同的词,因此像下面这样的情况无法正常工作: nlp('the koala eats/shoots/leaves').has('koala leaves') //false - **inter-sentence match:** 默认情况下,句子是顶层抽象单元。 若无 插件,则不支持跨句或多句匹配: nlp("that's it. Back to Winnipeg!").has('it back')//false - **nested match syntax:** 正则表达式的危险之美在于可以无限递归。 我们的匹配语法要弱得多。像下面这样的情况尚(尚未)支持: doc.match('(modern (major|minor))? general') 复杂匹配必须通过连续的 **.match()** 调用来实现。 - **dependency parsing:** 正确的句子变换需要理解句子的 [syntax tree](https://en.wikipedia.org/wiki/Parse_tree),我们目前尚未实现。 我们应当支持!欢迎在此方面提供帮助。 ##### 常见问题
#### 另请参阅: -   **[en-pos](https://github.com/finnlp/en-pos)** - 非常精巧的 JavaScript POS 标注器 _by [Alex Corvi](https://github.com/alexcorvi)_ -   **[naturalNode](https://github.com/NaturalNode/natural)** - JavaScript 中更精致的统计 NLP -   **[winkJS](https://winkjs.org/)** - JavaScript 中的 POS 标注器、分词器与机器学习 -   **[dariusk/pos-js ](https://github.com/dariusk/pos-js)** - JavaScript 版 fastTag 分支 -   **[compendium-js](https://github.com/Ulflander/compendium-js)** - JavaScript 中的 POS 与情感分析 -   **[nodeBox linguistics](https://www.nodebox.net/code/index.php/Linguistics)** - JavaScript 中的词形变化与屈折 -   **[reText](https://github.com/wooorm/retext)** - JavaScript 中令人印象深刻的 [text utilities](https://github.com/wooorm/retext/blob/master/doc/plugins.md) -   **[superScript](https://github.com/superscriptjs/superscript)** - JavaScript 对话引擎 -   **[jsPos](https://code.google.com/archive/p/jspos/)** - 久经考验的 Brill 标注器的 JavaScript 构建版 -   **[spaCy](https://spacy.io/)** - C/Python 实现的快速多语言标注器(tagger) -   **[Prose](https://github.com/jdkato/prose/)** - Joseph Kato 用 Go 编写的快速标注器 -   **[TextBlob](https://github.com/sloria/TextBlob)** - Python 标注器 MIT