REAL case insensitive version of str.replace
that keeps the letter case of the original expression (Doesn't only replace Foo
and foo
to ...foo...
but to ...Foo..
and ...foo...
).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | def iter_find(_str, to_find, n=0):
""" Finds all occurences of `to_find` in `_str`. Itering-ready. """
_str_len = len(_str)
to_find_len = len(to_find)
while n <= _str_len:
if _str[n:n+to_find_len] == to_find:
yield n
n += 1
def ireplace(text, old, new):
""" Replaces as occurences of `old` with the string pattern `new`.
The `new` variable has to be a string (additionally containing a
placeholder where the matches go (`%s`). """
assert(isinstance(text, str) and isinstance(old, str))
use_string_format = '%s' in new
old_len = len(old)
to_replace = []
for match in iter_find(text.lower(), old.lower()):
match = text[match:match+old_len]
if match not in to_replace:
if use_string_format:
to_replace.append((match, new % match))
else:
to_replace.append((match, new))
for rule in to_replace:
text = text.replace(*rule)
return text
|
I could be missing something, but it looks like the replacement text provided through the 'new' argument has to always contain the matching text from the original string somewhere in it via the '%s' placeholder -- which doesn't seem especially useful.
Oh yes, that would be nice to have. I changed the code :-)