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.
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | 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 lower(self): # Courtesy Duncan Booth
return self.__lowerCaseMe
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)
|
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.
Make less restrictive to be more like python strings. It is quite possible in python to compare strings against integers or other non strings. So in __cmp__ and __eq__ I have added a try:except block around the current line, and in the except part put the same line but without the call to lower() (as it is this that raises the exception). e.g.
Terrible idea. Use a case-insensitive dictionary instead.