docs/recipes.md
Copy-paste solutions for common tasks. Every snippet is real, verified output. Read concepts.md first if you haven't — especially the mutability rule, which trips up most of these.
import nlp from 'compromise'
Transform methods change the underlying document in place, and the View they return is the
selection, not the whole document. So read the result from the original doc:
let doc = nlp('I walk to work')
doc.verbs().toPastTense() // mutates doc; the returned view is just "walked"
doc.text() // 'I walked to work' ✅ read from doc
// ⚠️ common mistake — .text() here is only the matched selection:
nlp('I walk to work').verbs().toPastTense().text() // 'walked work' (not the whole sentence)
To transform a copy and leave the original alone, use .clone():
let doc = nlp('I walk')
let past = doc.clone().verbs().toPastTense().text() // 'walked'
doc.text() // 'I walk' (untouched)
let doc = nlp('Mary met Dr. John Smith in Paris.')
doc.people().out('array') // ['Mary', 'Dr. John Smith']
doc.places().out('array') // ['Paris.']
nlp('Google and Mary went to Paris.').topics().out('array') // ['Google', 'Paris.', 'Mary']
.topics() = people + places + organizations.
let doc = nlp('I walk to work')
doc.verbs().toPastTense(); doc.text() // 'I walked to work'
doc.verbs().toFutureTense(); doc.text() // 'I will walk to work'
Tense methods also exist on .sentences() for whole-sentence rewrites.
let doc = nlp('I love cats')
doc.replace('cats', 'dogs') // search-and-replace by pattern
doc.text() // 'I love dogs'
// replace whatever a selection matched:
let d2 = nlp('the cat sat')
d2.match('#Noun').replaceWith('dog')
d2.text() // 'the dog sat'
let doc = nlp('Mary called John')
doc.people().replaceWith('███')
doc.text() // '███ called ███'
There is also a built-in .redact() that removes people, places, emails, and phone numbers at
once. Note it does not currently redact organizations — remove those yourself with
doc.organizations().replaceWith('███') if you need to.
let doc = nlp('one good dog')
doc.nouns().toPlural(); doc.text() // 'one good dogs'
let d2 = nlp('three turnovers')
d2.nouns().toSingular(); d2.text() // 'three turnover'
nlp('it cost twelve dollars').numbers().get() // [12]
nlp('five hundred').numbers().toNumber().text() // '500' (words → digits)
nlp('it is 5 km').numbers().toText().text() // 'five' (digits → words)
Numbers also support .greaterThan(), .lessThan(), .between(), .add(), .subtract().
Money and fractions have their own selections (.money(), .fractions(), .percentages()).
let doc = nlp('the price of milk is high')
doc.match('price of [<thing>.]').groups('thing').text() // 'milk'
See match-syntax.md for the full pattern language and capture groups.
nlp('the deal is closed').has('#Determiner #Noun') // true
nlp('I love cats').has('love #Plural') // true
.has() returns a boolean and never mutates — ideal for routing/intent checks.
nlp('I am here. Are you ok?').questions().out('array') // ['Are you ok?']
nlp('I like cats. Dogs are loud.').sentences().if('#Plural').out('array')
// ['I like cats.', 'Dogs are loud.'] — keep only sentences containing a plural
let doc = nlp('he is happy')
doc.sentences().toNegative()
doc.text() // 'he is not happy'
let doc = nlp("she isn't here")
doc.contractions().expand()
doc.text() // 'she is not here'
nlp('I LOVE Café!!').normalize().text() // 'I LOVE Cafe!'
.normalize({ ... }) takes options for whitespace, case, unicode, punctuation, contractions, etc.
nlp('big cats').json()[0].terms.map(t => t.text) // ['big', 'cats']
nlp('hi there').json({ offset: true })[0].offset // { index: 0, start: 0, length: 8 }
.json() accepts flags to include offset, tags, normal, reduced, and more — see api.md.
At parse time, with a lexicon object:
nlp('kermit waved', { kermit: 'FirstName' }).people().out('array') // ['kermit']
Globally, with nlp.addWords() (use a valid tag):
nlp.addWords({ frodo: 'FirstName', gandalf: 'FirstName' })
nlp('frodo met gandalf').people().out('array') // ['frodo', 'gandalf']
nlp.plugin({
// add words to the lexicon
words: { kermit: 'FirstName' },
// add new tags to the tagset graph
tags: { Muppet: { isA: 'Person' } },
// add new chainable methods
api: (View) => {
View.prototype.exclaim = function () {
return this.post('!') // add '!' after each match
}
},
})
let doc = nlp('hello there')
doc.match('there').exclaim()
doc.text() // 'hello there!'
See concepts.md for .extend() and the full plugin shape, and the
plugins/ folder for real examples (dates, stats, wikipedia, …).
.match() returns nothing#Name, #Location, #Adj are not tags.doc.debug() to print how each word was actually tagged.{root} to match all conjugations.