striprtf
| Language | Python (3.8+) |
|---|---|
| License | BSD-3-Clause |
| Repository | github.com/joshy/striprtf |
| Documentation | README |
| Depends on | nothing |
| Read / write | reads RTF to plain text; doesn't write RTF |
striprtf has one function, rtf_to_text, which removes RTF markup and returns the text. It skips destinations like the font table, color table, stylesheet and pictures, turns \par and \line into newlines and \tab into tabs, decodes \'hh escapes using the document’s code page (\ansicpg) and \uN Unicode escapes, and keeps table cells separated by |. It started from a widely shared regex-based recipe and has been improved for real-world files, especially medical reports.
It’s a good fit for search indexing, data extraction and migrating RTF fields from databases. It doesn’t give you formatting or structure.
Installation#
pip install striprtf
Basic usage: extract text from an RTF file#
from striprtf.striprtf import rtf_to_text
with open("letter.rtf", encoding="ascii", errors="ignore") as f: # RTF is 7-bit ASCII
rtf = f.read()
text = rtf_to_text(rtf)
print(text)
How to set the fallback code page#
If the RTF has no \ansicpg, striprtf decodes \'hh bytes as cp1252. Pass another encoding for files from other locales:
text = rtf_to_text(rtf, encoding="cp1251") # Cyrillic Windows
How to ignore decoding errors#
text = rtf_to_text(rtf, errors="ignore") # or "replace"
How to convert a folder of RTF files to text#
from pathlib import Path
from striprtf.striprtf import rtf_to_text
for path in Path("reports").glob("*.rtf"):
rtf = path.read_text(encoding="ascii", errors="ignore")
path.with_suffix(".txt").write_text(rtf_to_text(rtf, errors="replace"), encoding="utf-8")
How to extract text from RTF stored in a database#
RTF fields often come as strings; pass them directly:
for row_id, rtf in cursor.execute("SELECT id, notes_rtf FROM notes"):
if rtf and rtf.lstrip().startswith("{\\rtf"):
print(row_id, rtf_to_text(rtf).strip()[:80])
Tips#
- Read files as ASCII (or Latin-1): non-ASCII characters in valid RTF are always escaped, so this is lossless.
- Embedded pictures and objects are skipped, so very large RTF files can produce short text.