Case-insensitive string comparison

Dale Strickland-Clark dale at riverhall.NOTHANKS.co.uk
Wed Apr 16 12:46:07 CEST 2003


"Avner Ben" <avner at skilldesign.com> wrote:

>Question:
>
>    Does standard Python have case-insensitive string comparison and search?
>
>        Avner.
>

This might help. 

This is a class you use in place of a string and it emulates a string
in all practical ways except that comparisons and lookups are case
insensitive. All uses of the string for assignments, however, yield
the original case.

We've found this very handy when using strings as dictionary indices
or when searching for Windows filenames in lists.

Some examples:
>>> poem = iStr("Mary had a little LAMB")
>>> poem == "mary had a little lamb"
1
>>> poem.find("LITTLE")
11
>>> poem.title()
'Mary Had A Little Lamb'
>>> poem
iStr('Mary had a little LAMB')
>>> 

Note that the hash value is the lower case value. If you use an iStr
as a dictionary index, you will need to make sure that lookups are
lower case too:

>>> filelist = {iStr('WINNT'): 0, iStr('Temp'): 0}
>>> 'winnt' in filelist
1
>>> 'WINNT' in filelist
0
>>> 'temp' in filelist
1
>>> 

The replace() method of the str class hasn't been tackled. If you use
replace on an iStr, it will operate as on a normal string.

I've submitted this to the Python Cookbook.


class iStr(str):
    """Case insensitive strings class.
    Performs like str except comparisons are case insensitive."""

    def __init__(self, strMe):
        str.__init__(self, strMe)
        self.__lowerCaseMe = strMe.lower()

    def __repr__(self):
        return "iStr(%s)" % str.__repr__(self)

    def __eq__(self, other):
        return self.__lowerCaseMe == other.lower()

    def __lt__(self, other):
        return self.__lowerCaseMe < other.lower()

    def __le__(self, other):
        return self.__lowerCaseMe <= other.lower()

    def __gt__(self, other):
        return self.__lowerCaseMe > other.lower()

    def __ne__(self, other):
        return self.__lowerCaseMe != other.lower()

    def __ge__(self, other):
        return self.__lowerCaseMe >= other.lower()

    def __cmp__(self, other):
        return cmp(self.__lowerCaseMe, other.lower())

    def __hash__(self):
        return hash(self.__lowerCaseMe)

    def __contains__(self, other):
        return other.lower() in self.__lowerCaseMe

    def count(self, other, *args):
        return str.count(self.__lowerCaseMe, other.lower(), *args)

    def endswith(self, other, *args):
        return str.endswith(self.__lowerCaseMe, other.lower(), *args)

    def find(self, other, *args):
        return str.find(self.__lowerCaseMe, other.lower(), *args)
    
    def index(self, other, *args):
        return str.index(self.__lowerCaseMe, other.lower(), *args)

    def rfind(self, other, *args):
        return str.rfind(self.__lowerCaseMe, other.lower(), *args)

    def rindex(self, other, *args):
        return str.rindex(self.__lowerCaseMe, other.lower(), *args)

    def startswith(self, other, *args):
        return str.startswith(self.__lowerCaseMe, other.lower(),
*args)

    
--
Dale Strickland-Clark
Riverhall Systems Ltd




More information about the Python-list mailing list