Welcome, guest | Sign In | My Account | Store | Cart

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...).

Python, 28 lines
 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

2 comments

Martin Miller 15 years ago  # | flag

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.

Jonas Haag (author) 14 years, 12 months ago  # | flag

Oh yes, that would be nice to have. I changed the code :-)

Created by Jonas Haag on Thu, 9 Apr 2009 (MIT)
Python recipes (4591)
Jonas Haag's recipes (1)

Required Modules

  • (none specified)

Other Information and Tasks