1

I need to capitalize the first letter of every word in a string using regular expressions:

>>> import re
>>> re.sub(r"\b(\S)", (r"\1").upper(), "foo bar")
'foo bar'

I expect the result to be 'Foo Bar' instead.

I have tried the title method and string.capwords, but both have issues as shown below:

>>> import string
>>> string.capwords("foo      bar   1a   ") 
'Foo Bar 1a'
>>> "1a".title() 
1A

Using the lambda expression as @Sebastian suggests in the comment below worked for me.

Anand
  • 3,690
  • 4
  • 33
  • 64
  • 1
    Is it necessary to use regular expressions? Can you use "foo bar".title()? – Wes Doyle Dec 27 '16 at 22:31
  • Possible duplicate of [How to capitalize the first letter of each word in a string (Python)?](http://stackoverflow.com/questions/1549641/how-to-capitalize-the-first-letter-of-each-word-in-a-string-python) – wildwilhelm Dec 27 '16 at 22:32
  • I tried that, but title doesn't seem to work right when the first character is numeric. For example, I want "1a" to remain unchanged, but "1a".title() returns "1A" – Anand Dec 27 '16 at 22:33
  • @WesDoyle @Anand try `string.capwords` instead – Uriel Dec 27 '16 at 22:34
  • string.capwords collapses all contiguous whitespaces into a single whitespace. So, `string.capwords("foo bar ")` returns `Foo Bar` and not `Foo Bar ` – Anand Dec 27 '16 at 22:37
  • 2
    You can use a function/lambda for the replacement, e.g. `re.sub(r"\b(\S)", lambda x: x.group().upper(), "foo bar")` – Sebastian Proske Dec 27 '16 at 22:38
  • @SebastianProske - that works! Thanks. – Anand Dec 27 '16 at 22:44

2 Answers2

2

If you are looking for a regex solution, the re.sub function can receive as a second argument a function:

>>> def t(x):                        
...    if x:                        
...        return x.group(0).upper()

>>> re.sub(r"\b(\S)", t, "foo bar") 
'Foo Bar'                       

>>> re.sub(r"\b(\S)", t, "1foo bar")
'1foo Bar'                      
Dekel
  • 60,707
  • 10
  • 101
  • 129
1

This seems to work too:

import string
' '.join([string.capitalize(word) for word in 'foo      bar   1a   '.split(' ')])

output:

'Foo      Bar   1a   '
gitaarik
  • 42,736
  • 12
  • 98
  • 105