Python convert all-caps into title case without messing with camel case

Question:

I’m using python3 and would like to turn strings that contain all caps words (separately or inside a word) into title case (first letter capitalized). I do not want to disrupt one-off capital letters in the middle of a word (camel case), but if there are repeated capitalized letters, I want to keep only the first one capitalized.

Here’s the desired behavior

>>> a = "TITLE BY DeSoto theHUMUNGUSone"
>>> print(myfunc(a))
Title By DeSoto TheHumungusone

In words, "capitalize the beginning of each word and then take any letter that follows a capital letter and make it lower case."

The str.title() does the initial letters the way I want, but it makes all intra-word letters lower case, rather than just those following the first.

I was playing with a regular expression approach that makes anything that follows an upper case letter lower case, but I kept getting every other letter capitalized.

Asked By: farnsy

||

Answers:

A regular expression substitution with a lambda is the way to go:

import re

a = "TITLE BY DeSoto theHUMUNGUSone"
print(re.sub('[A-Z]+', lambda x: x.group(0).title(), a))

Output:

Title By DeSoto theHumungusone
Answered By: Grismar

Haha this sounds like a leetcode problem! In addition to regex, you could use this little algorithm, which just makes a new string, and iterates through the characters, converting any following to lowercase when an uppercase is hit. You can easily modify it to make anything following spaces uppercase also.

b = ''
i = 0
while i < len(a):
    if a[i].isupper():
        b += a[i]
        for j in range(i + 1, len(a)):
            if a[j].isupper():
                b += a[j].lower()
            else:
                i = j - 1
                break
    else:
        b += a[i]
    i += 1
Answered By: PunkyMunky64

how about this one:

import re

a = "TITLE BY DeSoto theHUMUNGUSone"

def transform(a):
    chunks = []
    for chunk in re.findall(r'[a-z]*[A-Z]*[a-z]*[ ]?', a):
        if chunk:
            if chunk[0].isupper():
                chunk = chunk.capitalize()
                chunks.append(chunk.title())
            else:
                substring = chunk[0].upper()+chunk[1:]
                chunks.append(re.sub('[A-Z]+',lambda x:x.group().title(),substring))

    return ''.join(chunks)

transform(a)
Answered By: Aiden Zhao
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.