The bistring library provides non-destructive versions of common string processing operations like normalization, case folding, and find/replace. Each bistring remembers the original string, and how its substrings map to substrings of the modified version.
For example:
>>> from bistring import bistr
>>> s = bistr('饾暱饾枍饾枈 饾枛饾枤饾枎饾枅饾枑, 饾枃饾枟饾枖饾枩饾枔 馃 饾枏饾枤饾枓饾枙饾枠 饾枖饾枦饾枈饾枟 饾枡饾枍饾枈 饾枒饾枂饾枱饾枮 馃惗')
>>> s = s.normalize('NFKD') # Unicode normalization
>>> s = s.casefold() # Case-insensitivity
>>> s = s.replace('馃', 'fox') # Replace emoji with text
>>> s = s.replace('馃惗', 'dog')
>>> s = s.sub(r'[^\w\s]+', '') # Strip everything but letters and spaces
>>> s = s[:19] # Extract a substring
>>> s.modified # The modified substring, after changes
'the quick brown fox'
>>> s.original # The original substring, before changes
'饾暱饾枍饾枈 饾枛饾枤饾枎饾枅饾枑, 饾枃饾枟饾枖饾枩饾枔 馃'This allows you to perform very aggressive text processing completely invisibly.