Is there a way to make python str.partition ignore case?


December 2018


1.1k time


I am trying to make Python's str.partition function ignore case during the search, so

>>>partition_tuple = 'Hello moon'.partition('hello')
('', 'Hello', ' moon')


>>>partition_tuple = 'hello moon'.partition('hello')
('', 'hello', ' moon')

return as shown above.

Should I be using regular expressions instead?



Pardons, I should have been more specific. I want to find a keyword in a string, change it (by adding stuff around it) then put it back in. My plan to do this was make partitions and then change the middle section then put it all back together.


'this is a contrived example' 

with keyword 'contrived' would become:

'this is a <<contrived>> example'

and I need it to perform the <<>> even if 'contrived' was spelled with a capital 'C.'

Note that any letter in the word could be capitalized, not just the starting one.

The case needs to be preserved.

Another unique point to this problem is that there can be several keywords. In fact, there can even be a key phrase. That is to say, in the above example, the keywords could have been 'a contrived' and 'contrived' in which case the output would need to look like:

'this is <<a contrived>> example.'

6 answers


What is the actual problem you are trying using partition()?

No, partition() is case-sensitive and there is no way around it except by normalizing the primary string.


You can do this if you don't need to preserve the case:

>>> partition_tuple = 'Hello moon'.lower().partition('hello')
>>> partition_tuple
('', 'hello', ' moon')

However as you can see, this makes the resulting tuple lowercase as well. You cannot make partition case insensitive.


How about

re.split('[Hh]ello', 'Hello moon')

This gives

['', ' moon']

Now you have the pieces and you can put them back together as you please. And it preserves the case.

You can put multiple keywords in one regex (but read caution below)

re.split(r'[Hh]ello | moon', 'Hello moon')

Caution: re will use the FIRST one that matches and then ignore the rest.

So, putting in multiple keywords is only useful if there is a SINGLE keyword in each target.


You could also do this by writing your own case_insensitive_partition which could look something like this (barely tested but it did work at least in trivial cases):

def case_partition(text, sep):
    ltext = text.lower()
    lsep = sep.lower()
    ind = ltext.find(lsep)
    seplen = len(lsep)
    return (text[:ind], text[ind:ind+seplen], text[ind+seplen:])

Perhaps more info on the task would help us give a better answer. For example, is Bastien's answer sufficient, or does case need to be preserved?

If the string has the embedded space you could just use the str.split(sep) function.

But I am guessing you have a more complex task in mind. Please describe it more.


How about

'Hello moon'.lower().partition('hello')