如何将字符串中每个单词的首字母大写?

问题:如何将字符串中每个单词的首字母大写?

s = 'the brown fox'

…在这里做某事…

s 应该 :

'The Brown Fox'

最简单的方法是什么?

s = 'the brown fox'

…do something here…

s should be :

'The Brown Fox'

What’s the easiest way to do this?


回答 0

.title()一个字符串(ASCII或Unicode是细)的方法做到这一点:

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

但是,请注意文档中提到的带有嵌入式撇号的字符串。

该算法使用单词的简单语言独立定义作为连续字母的组。该定义在许多情况下都适用,但是它意味着缩略语和所有格中的撇号形成单词边界,这可能不是期望的结果:

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

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"

回答 1

.title()方法效果不佳,

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

试试string.capwords()方法,

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

capwordspython文档中

使用str.split()将参数分解为单词,使用str.capitalize()将每个单词大写,然后使用str.join()将大写的单词连接起来。如果不存在可选的第二个参数sep或“无”,则将空白字符替换为一个空格,并删除前导和尾随空白,否则将使用sep拆分和合并单词。

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.


回答 2

仅仅因为这种事情对我来说很有趣,所以这里有另外两个解决方案。

拆分为单词,对拆分组中的每个单词进行大写,然后重新加入。不管是什么,这都会将将单词分隔的空白变为单个空白。

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

编辑:我不记得我在写上面的代码时在想什么,但是没有必要建立一个明确的列表。我们可以使用生成器表达式以懒惰的方式进行操作。因此,这是一个更好的解决方案:

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

使用正则表达式匹配字符串的开头,或使用空格分隔单词,再加上一个非空格字符;用括号标记“匹配组”。编写一个函数,该函数接受一个match对象,并以大写形式返回空白的空白匹配组和非空白的字符匹配组。然后使用re.sub()替换图案。这个没有第一个解决方案的标点符号问题,也没有像我的第一个解决方案那样重做空白。这产生最好的结果。

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"

我很高兴研究了这个答案。我不知道re.sub()可以发挥作用!您可以在内部re.sub()进行非平凡的处理以产生最终结果!

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!


回答 3

以下是执行此操作的不同方法的摘要,它们将适用于所有这些输入:

""           => ""       
"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"     

-最简单的解决方案是将句子拆分成单词并大写第一个字母,然后将其重新组合在一起:

# 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(' ')) 

-如果您不想先使用花哨的生成器将输入字符串拆分成单词,请执行以下操作:

# 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)) )

-或不导入itertools:

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

-或者您可以使用正则表达式,来自steveha的答案

# 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)

现在,这些是其他一些已发布的答案,如果我们使用的单词定义是句子的开头或空格后的任何内容,则这些输入将无法按预期运行:

  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"      

使用”进行拆分将修复第二个输出,但是capwords()仍不适用于第一个输出

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

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

注意多个空格

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

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"                 

回答 4

@jibberia anwser的复制粘贴就绪版本:

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

Copy-paste-ready version of @jibberia anwser:

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

回答 5

当解决方案既简单又安全时,为什么要使join和for循环使您的生活复杂化?

只是这样做:

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

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:]

回答 6

如果str.title()对您不起作用,请自己大写。

  1. 将字符串分成单词列表
  2. 每个单词的首字母大写
  3. 将单词连接成一个字符串

单线:

>>> ' '.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"

清晰的例子:

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)

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)

回答 7

如果只想要第一个字母:

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

但是要大写每个单词:

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

If only you want the first letter:

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

But to capitalize each word:

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

回答 8

如果您访问[1:],则空字符串将引发错误,因此我将使用:

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

仅将首字母大写。

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.


回答 9

正如Mark所指出的,您应该使用.title()

"MyAwesomeString".title()

但是,如果要在django模板中将第一个字母大写,则可以使用以下命令:

{{ "MyAwesomeString"|title }}

或使用变量:

{{ myvar|title }}

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 }}

回答 10

建议的方法str.title()并非在所有情况下都有效。例如:

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

代替"A B 3c"

我认为,最好执行以下操作:

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'

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'

回答 11

尽管所有答案都已经令人满意,但是我将尝试覆盖所有2个额外的情况以及以前的所有情况。

如果空间不均匀并且您想要保持相同

string = hello    world i  am    here.

如果所有字符串都不以字母开头

string = 1 w 2 r 3g

在这里你可以使用

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

这会给你

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

我希望这不是多余的。

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.


回答 12

大写单词…

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

@ Gary02127注释,在解决方案工作标题下带有撇号

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))

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))

回答 13

不要忽视空白的保留。如果您要处理'fred flinstone'而得到'Fred Flinstone'而不是'Fred Flinstone',则说明您的空白空间已损坏。上述某些解决方案将失去空白。这是一个适用于Python 2和3并保留空白的解决方案。

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

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

快速功能适用于Python 3

Python 3.6.9 (default, Nov  7 2019, 10:44:02) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> capitalizeFirtChar = lambda s: s[:1].upper() + s[1:]
>>> print(capitalizeFirtChar('помните своих Предковъ. Сражайся за Правду и Справедливость!'))
Помните своих Предковъ. Сражайся за Правду и Справедливость!
>>> print(capitalizeFirtChar('хай живе вільна Україна! Хай живе Любовь поміж нас.'))
Хай живе вільна Україна! Хай живе Любовь поміж нас.
>>> print(capitalizeFirtChar('faith and Labour make Dreams come true.'))
Faith and Labour make Dreams come true.

A quick function worked for Python 3

Python 3.6.9 (default, Nov  7 2019, 10:44:02) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> capitalizeFirtChar = lambda s: s[:1].upper() + s[1:]
>>> print(capitalizeFirtChar('помните своих Предковъ. Сражайся за Правду и Справедливость!'))
Помните своих Предковъ. Сражайся за Правду и Справедливость!
>>> print(capitalizeFirtChar('хай живе вільна Україна! Хай живе Любовь поміж нас.'))
Хай живе вільна Україна! Хай живе Любовь поміж нас.
>>> print(capitalizeFirtChar('faith and Labour make Dreams come true.'))
Faith and Labour make Dreams come true.

回答 15

用不均匀的空格大写字符串

好吧,我知道这是一个古老的问题,可能答案几乎已经用尽,但我想补充一下@Amit Gupta的非均匀空间。从最初的问题开始,我们想将字符串中的每个单词都大写s = 'the brown fox'。如果字符串的s = 'the brown fox'空格不均匀怎么办。

def solve(s):
    # if you want to maintain the spaces in the string, s = 'the brown      fox'
    # use s.split(' ') instead of s.split(). 
    # s.split() returns ['the', 'brown', 'fox']
    # while s.split(' ') returns ['the', 'brown', '', '', '', '', '', 'fox']
    capitalized_word_list = [word.capitalize() for word in s.split(' ')]
    return ' '.join(capitalized_word_list)

Capitalize string with non-uniform spaces

Well, I understand this is an old question and probably answers may have nearly been exhausited, but I would like to add to @Amit Gupta’s point of non-uniform spaces. From the original question, we would like to capitalize every word in the string s = 'the brown fox'. What if the string was s = 'the brown fox' with non-uniform spaces.

def solve(s):
    # if you want to maintain the spaces in the string, s = 'the brown      fox'
    # use s.split(' ') instead of s.split(). 
    # s.split() returns ['the', 'brown', 'fox']
    # while s.split(' ') returns ['the', 'brown', '', '', '', '', '', 'fox']
    capitalized_word_list = [word.capitalize() for word in s.split(' ')]
    return ' '.join(capitalized_word_list)

回答 16

**如果您想缩小尺寸**

 #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

**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

回答 17

我真的很喜欢这个答案:

@jibberia anwser的复制粘贴就绪版本:

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

但是,我发送的某些行拆分了一些空白的”字符,这些字符在尝试执行s [1:]时会导致错误。可能有更好的方法来执行此操作,但是我必须添加if len(s)> 0,例如

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

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])