How to capitalize the first letter of each word in a string?

僤鯓⒐⒋嵵緔 提交于 2019-11-26 00:31:10

问题


s = \'the brown fox\'

...do something here...

s should be :

\'The Brown Fox\'

What\'s the easiest way to do this?


回答1:


The .title() method of a string (either ASCII or Unicode is fine) does this:

>>> "hello world".title()
'Hello World'
>>> u"hello world".title()
u'Hello World'

However, look out for strings with embedded apostrophes, as noted in the docs.

The algorithm uses a simple language-independent definition of a word as groups of consecutive letters. The definition works in many contexts but it means that apostrophes in contractions and possessives form word boundaries, which may not be the desired result:

>>> "they're bill's friends from the UK".title()
"They'Re Bill'S Friends From The Uk"



回答2:


The .title() method can't work well,

>>> "they're bill's friends from the UK".title()
"They'Re Bill'S Friends From The Uk"

Try string.capwords() method,

import string
string.capwords("they're bill's friends from the UK")
>>>"They're Bill's Friends From The Uk"

From the python docs on capwords:

Split the argument into words using str.split(), capitalize each word using str.capitalize(), and join the capitalized words using str.join(). If the optional second argument sep is absent or None, runs of whitespace characters are replaced by a single space and leading and trailing whitespace are removed, otherwise sep is used to split and join the words.




回答3:


Just because this sort of thing is fun for me, here are two more solutions.

Split into words, initial-cap each word from the split groups, and rejoin. This will change the white space separating the words into a single white space, no matter what it was.

s = 'the brown fox'
lst = [word[0].upper() + word[1:] for word in s.split()]
s = " ".join(lst)

EDIT: I don't remember what I was thinking back when I wrote the above code, but there is no need to build an explicit list; we can use a generator expression to do it in lazy fashion. So here is a better solution:

s = 'the brown fox'
s = ' '.join(word[0].upper() + word[1:] for word in s.split())

Use a regular expression to match the beginning of the string, or white space separating words, plus a single non-whitespace character; use parentheses to mark "match groups". Write a function that takes a match object, and returns the white space match group unchanged and the non-whitespace character match group in upper case. Then use re.sub() to replace the patterns. This one does not have the punctuation problems of the first solution, nor does it redo the white space like my first solution. This one produces the best result.

import re
s = 'the brown fox'

def repl_func(m):
    """process regular expression match groups for word upper-casing problem"""
    return m.group(1) + m.group(2).upper()

s = re.sub("(^|\s)(\S)", repl_func, s)


>>> re.sub("(^|\s)(\S)", repl_func, s)
"They're Bill's Friends From The UK"

I'm glad I researched this answer. I had no idea that re.sub() could take a function! You can do nontrivial processing inside re.sub() to produce the final result!




回答4:


Here's a summary of different ways to do it, they will work for all these inputs:

""           => ""       
"a b c"      => "A B C"             
"foO baR"    => "FoO BaR"      
"foo    bar" => "Foo    Bar"   
"foo's bar"  => "Foo's Bar"    
"foo's1bar"  => "Foo's1bar"    
"foo 1bar"   => "Foo 1bar"     

- The simplest solution is to split the sentence into words and capitalize the first letter then join it back together:

# Be careful with multiple spaces, and empty strings
# for empty words w[0] would cause an index error, 
# but with w[:1] we get an empty string as desired
def cap_sentence(s):
  return ' '.join(w[:1].upper() + w[1:] for w in s.split(' ')) 

- If you don't want to split the input string into words first, and using fancy generators:

# Iterate through each of the characters in the string and capitalize 
# the first char and any char after a blank space
from itertools import chain 
def cap_sentence(s):
  return ''.join( (c.upper() if prev == ' ' else c) for c, prev in zip(s, chain(' ', s)) )

- Or without importing itertools:

def cap_sentence(s):
  return ''.join( (c.upper() if i == 0 or s[i-1] == ' ' else c) for i, c in enumerate(s) )

- Or you can use regular expressions, from steveha's answer:

# match the beginning of the string or a space, followed by a non-space
import re
def cap_sentence(s):
  return re.sub("(^|\s)(\S)", lambda m: m.group(1) + m.group(2).upper(), s)

Now, these are some other answers that were posted, and inputs for which they don't work as expected if we are using the definition of a word being the start of the sentence or anything after a blank space:

  return s.title()

# Undesired outputs: 
"foO baR"    => "Foo Bar"       
"foo's bar"  => "Foo'S Bar" 
"foo's1bar"  => "Foo'S1Bar"     
"foo 1bar"   => "Foo 1Bar"      

  return ' '.join(w.capitalize() for w in s.split())    
  # or
  import string
  return string.capwords(s)

# Undesired outputs:
"foO baR"    => "Foo Bar"      
"foo    bar" => "Foo Bar"      

using ' ' for the split will fix the second output, but capwords() still won't work for the first

  return ' '.join(w.capitalize() for w in s.split(' '))    
  # or
  import string
  return string.capwords(s, ' ')

# Undesired outputs:
"foO baR"    => "Foo Bar"      

Be careful with multiple blank spaces

  return ' '.join(w[0].upper() + w[1:] for w in s.split())
# Undesired outputs:
"foo    bar" => "Foo Bar"                 



回答5:


Copy-paste-ready version of @jibberia anwser:

def capitalize(line):
    return ' '.join(s[:1].upper() + s[1:] for s in line.split(' '))



回答6:


Why do you complicate your life with joins and for loops when the solution is simple and safe??

Just do this:

string = "the brown fox"
string[0].upper()+string[1:]



回答7:


If str.title() doesn't work for you, do the capitalization yourself.

  1. Split the string into a list of words
  2. Capitalize the first letter of each word
  3. Join the words into a single string

One-liner:

>>> ' '.join([s[0].upper() + s[1:] for s in "they're bill's friends from the UK".split(' ')])
"They're Bill's Friends From The UK"

Clear example:

input = "they're bill's friends from the UK"
words = input.split(' ')
capitalized_words = []
for word in words:
    title_case_word = word[0].upper() + word[1:]
    capitalized_words.append(title_case_word)
output = ' '.join(capitalized_words)



回答8:


If only you want the first letter:

>>> 'hello world'.capitalize()
'Hello world'

But to capitalize each word:

>>> 'hello world'.title()
'Hello World'



回答9:


An empty string will raise an Error if you access [1:], therefore I would use:

def my_uppercase(title):
    if not title:
       return ''
    return title[0].upper() + title[1:]

to uppercase the first letter only.




回答10:


As Mark pointed out you should use .title():

"MyAwesomeString".title()

However, if would like to make the first letter uppercase inside a django template, you could use this:

{{ "MyAwesomeString"|title }}

or using a variable:

{{ myvar|title }}



回答11:


To capitalize words...

str = "this is string example....  wow!!!";
print "str.title() : ", str.title();

@Gary02127 comment, below solution work title with apostrophe

import re

def titlecase(s):
    return re.sub(r"[A-Za-z]+('[A-Za-z]+)?", lambda mo: mo.group(0)[0].upper() + mo.group(0)[1:].lower(), s)

text = "He's an engineer, isn't he? SnippetBucket.com "
print(titlecase(text))



回答12:


The suggested method str.title() does not work in all cases. For example:

string = "a b 3c"
string.title()
> "A B 3C"

instead of "A B 3c".

I think, it is better to do something like this:

def capitalize_words(string):
    words = string.split(" ") # just change the split(" ") method
    return ' '.join([word.capitalize() for word in words])

capitalize_words(string)
>'A B 3c'



回答13:


Don't overlook the preservation of white space. If you want to process 'fred flinstone' and you get 'Fred Flinstone' instead of 'Fred Flinstone', you've corrupted your white space. Some of the above solutions will lose white space. Here's a solution that's good for Python 2 and 3 and preserves white space.

def propercase(s):
    return ''.join(map(''.capitalize, re.split(r'(\s+)', s)))



回答14:


**In case you want to downsize **

 #Assuming you are opening a new file   
 with open(input_file) as file:
     lines = [x for x in reader(file) if x]
 #for loop to parse the file by line
 for line in lines:
           name = [x.strip().lower() for x in line if x]
           print(name) #check the result



回答15:


Although all the answer are already satisfactory but I'll try to cover the 2 extra cases along with the all the previous case.

if the spaces are not uniform and you want to maintain the same

string = hello    world i  am    here.

if all the string are not starting from alphabets

string = 1 w 2 r 3g

Here you can use this

def solve(s):
    a = s.split(' ')
    for i in range(len(a)):
        a[i]= a[i].capitalize()
    return ' '.join(a)

this will give you

output = Hello    World I  Am    Here
output = 1 W 2 R 3g

I hope this is not redundant.




回答16:


I really like this answer:

Copy-paste-ready version of @jibberia anwser:

def capitalize(line):
    return ' '.join([s[0].upper() + s[1:] for s in line.split(' ')])

But some of the lines that I was sending split off some blank '' characters that caused errors when trying to do s[1:]. There is probably a better way to do this, but I had to add in a if len(s)>0, as in

return ' '.join([s[0].upper() + s[1:] for s in line.split(' ') if len(s)>0])


来源:https://stackoverflow.com/questions/1549641/how-to-capitalize-the-first-letter-of-each-word-in-a-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!