文字列内の各単語の最初の文字を大文字にする方法は?


回答:


990

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

56
私は次のようなもので所有問題を回避します" ".join(w.capitalize() for w in s.split())
mehtunguh

3
ほとんどの文字列では、所有格でさえも大文字になるため、これは安全ではありません。

10
string.title()に問題があります。たとえばを使用すると"e g 3b"、望ましい結果はになります"E G 3b"。ただし、を"e g 3b".title()返します"E G 3B"
ソレン

7
:これはこれも原因となりますことを心に留めておいてくださいIn [2]: 'tEst'.title() Out[2]: 'Test'
ジョナスLibbrecht

4
すばらしい答えであり、コメントは、Pythonではすべてが必要な動作をするわけではないことを強調していますが、そうするための便利な方法は常にあります。最も便利な方法は、多くの場合、python-titlecase
Aaron3468

189

.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 docsから:

str.split()を使用して引数を単語に分割し、str.capitalize()を使用して各単語を大文字にし、str.join()を使用して大文字の単語を結合します。オプションの2番目の引数sepがないかNoneの場合、一連の空白文字は1つのスペースに置き換えられ、先頭と末尾の空白が削除されます。それ以外の場合は、sepを使用して単語を分割および結合します。


2
Capwordsはまだ不足しており、などの処理を行いません"There once was a string with an 'that had words right after it and then closed'"。この例では、を除くすべての世界thatが期待どおりに大文字になっています。結果は"There Once Was A String With An 'that Had Words Right After It And Then Closed'"
devonbleibtrey 2016年

それでも、これtitle()は通常の状況よりもうまく機能します。私の状況でtitle()は、アクセントまたは分音記号のある名前に対してcapwords()は正しく処理されていても、正しくない出力が返されます。
houcros

1
良いですが、それでも「英国/英国」の区別が
めちゃくちゃです

1
@Chen Houwu、英国/英国は完璧な反例です。Pythonが同様の方法を使用して既存の大文字を小文字にしないようにするにはどうすればよいですか?
h0r53

105

このようなことが私にとって楽しいからといって、次の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())

正規表現を使用して、文字列の先頭、または単語を区切る空白文字に加えて、空白以外の単一の文字を照合します。括弧を使用して「一致グループ」をマークします。一致オブジェクトを取り、空白の一致グループを変更せずに、空白以外の文字の一致グループを大文字で返す関数を記述します。次に、を使用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()行って、最終結果を生成できます!


1
スライスを使用するソリューションの+1。残りの単語の大文字を変更せずに最初の文字を大文字にするものが必要でした(たとえば、Fooはfooになりますが、FOOはfOOになります)。これは完璧でした。
TomNysetvold

1
capitalizeは最初の文字を大文字にして残りを小文字に戻します
Vanuan

@バヌアン、あなたは正しいです!doc文字列の説明では、最初の文字を大文字にするだけだと思っていましたが、実際の動作は正しいです。答えを編集します。ヘッズアップありがとうございます。
steveha

これは何のように見えるstring.capwords陳Houwuの答えのドキュメントによると、ありません。
エイドリアンキースター

1
上記の回答では、s.split()を使用する代わりに、s.split( '')を使用する方が良いと思います。これは、文字列にいくつかの二重スペースがあり、結合時にこれらの二重スペースを維持したい場合、s.plit( '')はスペースを維持するのに役立ちますが、s.split()はそうしません
manpikin

21

これを行うためのさまざまな方法の概要を以下に示します。これらはこれらすべての入力に対して機能します。

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

分割に ''を使用すると、2番目の出力が修正されますが、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"                 

包括的な要約のための+1。(すべての単語ではなく)数字に続く単語のみを大文字にする方法を探しています。これを示す答えを追加してください。たとえば、は数字の後に続くので大文字でlower 123 upper返されます。私はそれがOPの質問の範囲を超えていることを知っていますが、あなたのすでに広範囲な答えへの素晴らしいアドオンです。前もって感謝します。lower 123 Upperupper
ProGrammer 2018年

この場合のニーズに合わせて、上記の方法のいくつかを変更できます。ただし、ほとんどの人が求めているものではないため、回答の一部としては追加しません。私はそれの正規表現バージョンを使用し、"([0-9]+)(\s+.)"代わりに使用します"(^|\s)(\S)"(1つ以上の数字、1つ以上のスペース、その後に任意の文字が続く)、または "([0-9]+)(\s*.)"「ゼロ以上の」スペースの後の文字を大文字にしたい場合番号
aljgom

私はそれを調べて、必ず別の特別なケースについて考えました。たとえば、上記のスニペットを変更して文字列を取得し、たとえばの代わりにWW1 - the great war出力します。略語で問題を確認しますか?このケースを示すものを追加してもよろしいですか?私はこれについてしばらく疑問に思っており、それを行う方法を考えることができません。WW1 - The Great WarWw1 ...
ProGrammer 2018年

上記の最初の方法では、入力文字列ですでに大文字になっている文字は変更されないため、次のようWW1に出力されますWW1
aljgom

15

@jibberia anwserのコピーアンドペースト対応バージョン:

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

2
リストを作成する必要はありません。str.joinジェネレータを受け入れます。
warvariuc 2015年

@warvariucジェネレーターを活用するためにこのコードをどのように変更しますか?
Konstantin Spirin 2015年


1
@warvariucはjoingen exps を受け入れることを言及するのに最適ですが、str.join特に場合には、リスト内包表記を使用することが一般的に推奨されます。これはjoin、引数に対して2回繰り返されるため、ジェネレーターではなく、すぐに使えるリストを提供する方が速いためです。
Bhargav Rao

1
@BhargavRaoなぜstr.join引数を2回繰り返す必要があるのでしょうか?確認したところ、チェックしていません。小さなシーケンスのリストの理解は確かに高速ですが。
warvariuc

12

ソリューションがシンプルで安全なのに、結合とforループで生活を複雑にしているのはなぜですか?

これを行うだけです:

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

2
複数の単語が存在する可能性があるためです。
Arnaud、

1
はい。でも、最初の文字だけを大文字にしたい場合がよくあります。これがその方法です。
2016

1
あなたはそれからただ使ってみません"the brown fox".capitalize()か?
ラッキードナルド2016

2
多分私はオンにしたくないので@luckydonald 'this is John''This is john'
janek37

これを単純に行うためのより良い方法ではありませんstring.capitalize()(本質的に@luckydonaldをエコーし​​ます)
Hassan Baig

10

str.title()が機能しない場合は、自分で大文字を使用してください。

  1. 文字列を単語のリストに分割する
  2. 各単語の最初の文字を大文字にします
  3. 単語を1つの文字列に結合する

一発ギャグ:

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

1
このソリューションの興味深い点の1つは、特別な空白をなくすことです。状況によっては重要でない場合があります。
mklauber '17年

8

最初の文字が必要な場合のみ:

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

しかし、各単語を大文字にするには:

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

慎重な理由が'hello New York'.capitalize()ある'Hello new york'
user2314737

5

空の文字列は、[1:]にアクセスするとエラーが発生するため、次のように使用します。

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

最初の文字のみを大文字にします。


それは何のstr.capitalizeためですか?
Eugene Pakhomov 2017年

4
@Eugene、はい、残念ながら、望ましくない可能性のある他のすべての文字を小文字にしてください。:/
Wim Feijen

return title[:1].upper() + title[1:]そのように空の文字列をスライスすると2つの空の文字列が得られ、結合して空の文字列が作成されるため、この問題にも対処できます
aljgom

3

Markが指摘したように、以下を使用する必要があります.title()

"MyAwesomeString".title()

ただし、djangoテンプレート内で最初の文字を大文字にする場合は、次のように使用できます。

{{ "MyAwesomeString"|title }}

または変数を使用:

{{ myvar|title }}

3

推奨されるメソッド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'

1
ただし、それらを区切るスペースの数が1ではない場合、エラーが発生する可能性があります。参考:ハッカーランクの問題
Divakar Rajesh

3

すべての答えはすでに満足のいくものですが、私は前のすべてのケースと一緒に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

これが冗長でないことを願っています。


2
不均一なスペースのケースを強調表示していただきありがとうございます。上記のいくつかの回答では、s.split( '')の代わりにs.split()を使用しています。不均一なスペースの場合、s.split( '')を使用すると、不均一なスペースが確実に維持されることに注意してください。ありがとうございました
manpikin

これは、スペースが不揃いな単語や、数字で始まる単語に最適です。ありがとう:)
Amresh Giri

2

単語を大文字にする...

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

既存の関数を使用すると、Pythonで高速に実行できます。
Tejasタンク

title()はアポストロフィを処理しないので、私はあまり好きではありません。"私は言えない" .title()は "私には言えない"を返します
Gary02127

Gary02127私は答えを更新しました@、見てください、あまりにもあなたの問題領域で完璧に働いた
Tejasタンク

1

ホワイトスペースの保存を見落とさないでください。処理'fred flinstone'したいのにの'Fred Flinstone'代わりに取得した場合'Fred Flinstone'、空白が破損しています。上記のソリューションのいくつかは空白を失います。Python 2と3に適しており、空白を維持するソリューションを次に示します。

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

0

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.

0

不均一なスペースで文字列を大文字にする

まあ、私はこれが古い質問であることを理解しており、おそらく答えはほぼ尽きているかもしれませんが、@ 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)

..ブラウンとフォックスの間の空白でない場合、コードはタブを補正できません;-)
ZF007

-1

**ダウンサイズしたい場合**

 #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

-2

私はこの答えが本当に好きです:

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

2
これは非常に複雑です。長さをチェックすることまでしますか?!非効率的な。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.