Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
FlashText is a Python library for finding known keywords in text and replacing aliases with canonical names. It is useful when you have a fixed vocabulary—such as skills, product names, or locations—and want deterministic matching across many documents. It is not a general NLP system: it does not infer meaning, recognize unseen entities, or match typos. The original PyPI package’s latest listed release is 2.7 from February 16, 2018, so test it on your target Python version before adopting it in a new production project.
What FlashText is for
FlashText addresses a specific problem: efficiently checking text against a known list of terms. You can use it to extract normalized labels, such as finding several resume skill aliases and returning a standard skill name, or to replace product and location aliases in documents. The original paper describes this kind of dictionary-driven matching, including matching large skill lists against resumes and normalizing synonyms. Read the original FlashText paper.
Think of it as a dictionary matcher, not an NLP pipeline. It only finds entries you put in its vocabulary. It does not tokenize text linguistically, stem or lemmatize words, identify entities it has never seen, resolve ambiguous meanings, or understand semantic similarity.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
How matching works
FlashText stores keywords in a trie and scans the input character by character. Its algorithm is inspired by Aho–Corasick but designed around complete-word matching. The paper describes search and replacement as O(N) with respect to document length under its algorithmic model; the dictionary still occupies memory, and real performance depends on the vocabulary, documents, and workload. The paper’s reported speed comparisons are benchmark-specific, not guarantees that FlashText will always outperform regular expressions. See the algorithm and benchmark context.
#1 Best Overall
When a shorter keyword is a prefix of a longer phrase, FlashText favors the longer match. For example, if both Machine and Machine Learning are entries, the phrase Machine Learning is treated as the longer match rather than two separate keywords. This is useful for canonicalizing phrases, but not if your application requires every overlapping match.
Install it and check package status
Use a virtual environment and install through the same Python interpreter that will run your code:
python -m venv .venv
source .venv/bin/activate # macOS/Linux
.venvScriptsActivate.ps1 # Windows PowerShell
python -m pip install flashtext==2.7
python -c "from flashtext import KeywordProcessor; print('ok')"
The package documentation gives pip install flashtext as the basic installation command. PyPI lists version 2.7, released February 16, 2018, and classifiers only through Python 3.6. That metadata does not prove the package fails on newer interpreters, but neither should a successful install be treated as evidence of current official compatibility. Pin the version and test imports, matching behavior, and output on the Python version you deploy. FlashText on PyPI.
Extract normalized keywords
Create a KeywordProcessor, add terms, and call extract_keywords(). A supplied value becomes the normalized result; if you omit it, FlashText returns the keyword itself.
from flashtext import KeywordProcessor
kp = KeywordProcessor()
kp.add_keyword("Big Apple", "New York")
kp.add_keyword("Bay Area")
text = "I love Big Apple and Bay Area."
print(kp.extract_keywords(text))
# ['New York', 'Bay Area']
By default, matching is case-insensitive. Add case_sensitive=True when capitalization distinguishes identifiers, acronyms, or product codes:
Rank #2
kp = KeywordProcessor(case_sensitive=True)
kp.add_keyword("Big Apple", "New York")
kp.add_keyword("Bay Area")
print(kp.extract_keywords("I love big Apple and Bay Area."))
# ['Bay Area']
Case-insensitive matching is convenient for ordinary prose, but can collapse terms whose capitalization carries meaning. Test acronyms, mixed-case identifiers, and language-specific case behavior if those occur in your data.
Replace aliases with canonical names
Use replace_keywords() when the desired output is transformed text rather than a list of matches:
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →from flashtext import KeywordProcessor
kp = KeywordProcessor()
kp.add_keyword("Big Apple", "New York")
kp.add_keyword("Bay Area", "San Francisco Bay Area")
kp.add_keyword("New Delhi", "NCR region")
text = "I love Big Apple, Bay Area, and new delhi."
normalized = kp.replace_keywords(text)
print(normalized)
# I love New York, San Francisco Bay Area, and NCR region.
The method returns a new string; it does not mutate the input. Replacement is mechanical, not context-aware: if a term has different meanings in different sentences, FlashText will not decide which meaning applies.
Get source spans or structured labels
Pass span_info=True to get the normalized value and the match’s start and end positions in the original input. The end offset is exclusive, as in a Python slice: text[7:16] is the nine-character string Big Apple.
kp = KeywordProcessor()
kp.add_keyword("Big Apple", "New York")
kp.add_keyword("Bay Area")
text = "I love Big Apple and Bay Area."
print(kp.extract_keywords(text, span_info=True))
# [('New York', 7, 16), ('Bay Area', 21, 29)]
Spans help with highlighting, annotations, and structured records. If you also replace the text, retain spans from the original string: a replacement of a different length shifts later positions in the output.
You can also store metadata as a value for extraction:
kp = KeywordProcessor()
kp.add_keyword("Taj Mahal", ("Monument", "Taj Mahal"))
kp.add_keyword("Delhi", ("Location", "Delhi"))
print(kp.extract_keywords("Taj Mahal is in Delhi."))
# [('Monument', 'Taj Mahal'), ('Location', 'Delhi')]
Structured values are for extraction; the package documentation notes that replacement does not work with tuple-valued metadata in the same way. Keep a separate string-to-string mapping when you also need substitutions. The package examples cover extraction, spans, and metadata.
Load and maintain a larger vocabulary
For a small list, add keywords directly or load a list:
kp.add_keywords_from_list(["java", "python", "machine learning"])
For aliases grouped under canonical names, use a dictionary whose keys are canonical labels and whose values are lists of aliases:
aliases = {
"Java": ["java", "java_2e", "java programming"],
"Product Management": ["PM", "product manager"],
}
kp.add_keywords_from_dict(aliases)
The API also supports a keyword file. Lines may use alias=>canonical or contain one keyword per line; load it with add_keyword_from_file("keywords.txt"). See the FlashText API documentation for the file format and methods.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsKeep vocabulary data versioned and validate it before loading. Decide how duplicate aliases and aliases assigned to multiple categories should be handled, and test case, punctuation, and spacing variants. You can remove terms with remove_keyword(), remove_keywords_from_list(), or remove_keywords_from_dict(); inspect the processor with len(kp), "alias" in kp, kp.get_keyword("alias"), and kp.get_all_keywords(). len() counts stored terms, not just canonical labels. See the package’s keyword management examples.
Understand word boundaries before relying on results
FlashText’s complete-word behavior prevents an entry such as Apple from matching inside Pineapple. Its documented default treats characters outside [A-Za-z0-9_] as word boundaries. That definition can produce surprising results for hyphens, slashes, identifiers, symbols, and text containing non-ASCII letters; it is not interchangeable with Python regex b, Unicode word segmentation, or a language-aware tokenizer.
You can change the boundary set with add_non_word_boundary(). For example, making slash a non-boundary character affects whether terms on either side of / count as separately bounded matches:
kp.add_non_word_boundary("/")
Choose this setting to reflect your identifiers and text format, not merely to make one example pass. Test terms adjacent to hyphens, slashes, underscores, punctuation, digits, accented letters, and scripts used in your data. The FlashText documentation describes its boundary behavior.
Recommended Free Tools
Build a test set for your vocabulary
Exact matching makes the dictionary and its boundary rules part of your application’s behavior. A small, deliberate test set can catch both missed terms and false positives before a vocabulary change reaches production.
Best Value
- Aliases: include expected spelling, spacing, punctuation, and capitalization variants.
- Near misses: test a keyword inside a larger word, such as
AppleversusPineapple. - Ambiguity: check short terms such as
AI,Go, orJavain contexts where they may mean something else. - Overlaps: verify which result wins when a short keyword and a longer phrase share text.
- Unicode: try accented characters, non-Latin scripts, combining marks, and punctuation found in real inputs.
- Spans and replacements: confirm offsets refer to the original text and that output substitutions do not break downstream position handling.
If a term is missing, check that the exact alias is present, the case setting is intended, and punctuation or adjacent characters do not change its boundaries. Then check for Unicode differences and overlapping longer phrases. Reduce the issue to one keyword and one sentence so the matching rule is clear.
Choose the right tool for the matching problem
| Need | Good first choice | Why |
|---|---|---|
| Many fixed, exact terms to extract or replace | FlashText | Dictionary-driven matching with canonical outputs. |
| Structural patterns, capture groups, dates, or arbitrary substrings | Regular expressions | Regex expresses pattern structure rather than requiring a fixed term list. |
| Typos, noisy text, or similarity scores | RapidFuzz | It provides fuzzy matching metrics and extraction helpers; it solves a different problem from exact boundary matching. RapidFuzz project. |
| Contextual entities, tokenization, lemmatization, or linguistic annotations | spaCy or another NLP pipeline | A language-aware pipeline or model is needed when context and linguistic structure matter. |
| Distributed retrieval, ranking, filtering, or a vocabulary too large for each process | Search engine or database index | Indexes provide centralized, persistent, queryable search rather than in-process text transformation. |
| Broad recognition or classification without maintaining models and infrastructure | Managed NLP API | Consider cloud data handling, latency, cost, and vendor dependency alongside capability. |
Regular expressions remain useful when you need a structural pattern or a small set of patterns; FlashText’s documentation presents it as a complement rather than a universal replacement. FlashText package page.
Is FlashText a sensible choice in 2026?
It can be, when your requirements are narrow: a known vocabulary, exact matching, and extraction or replacement. The original package is small and deterministic, but its age makes compatibility and maintenance a real consideration for a new production deployment. Test it under your target interpreter and with your actual text; review the original implementation and its MIT license at the FlashText GitHub repository.
Free tools Windows power users keep installed
One-click scans. No signup required.
Do not assume a similarly named fork is interchangeable. For example, flashtext-i18n is an internationalization-focused fork signal, not proof that its API or matching behavior is a drop-in replacement. Evaluate any alternative’s license, supported Python versions, boundary rules, case handling, span offsets, and replacement behavior against your tests.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

