Wie kann man den ersten Buchstaben jedes Wortes in einer Zeichenfolge groß schreiben?

588
s = 'the brown fox'

... hier etwas tun ...

s sollte sein :

'The Brown Fox'

Was ist der einfachste Weg, dies zu tun?

TIMEX
quelle

Antworten:

989

Die .title()Methode einer Zeichenfolge (entweder ASCII oder Unicode ist in Ordnung) führt Folgendes aus:

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

Achten Sie jedoch auf Zeichenfolgen mit eingebetteten Apostrophen, wie in den Dokumenten angegeben.

Der Algorithmus verwendet eine einfache sprachunabhängige Definition eines Wortes als Gruppen aufeinanderfolgender Buchstaben. Die Definition funktioniert in vielen Zusammenhängen, bedeutet jedoch, dass Apostrophe in Kontraktionen und Possessiven Wortgrenzen bilden, die möglicherweise nicht das gewünschte Ergebnis sind:

>>> "they're bill's friends from the UK".title()
"They'Re Bill'S Friends From The Uk"
Mark Rushakoff
quelle
56
Ich vermeide das besitzergreifende Problem mit so etwas wie" ".join(w.capitalize() for w in s.split())
mehtunguh
3
Dies ist für die meisten Zeichenfolgen nicht sicher, da jedes Wort, das sogar besitzergreifend ist, in Großbuchstaben geschrieben wird.
10
Es gibt ein Problem mit string.title (). Wenn Sie zum Beispiel verwenden, "e g 3b"wäre das gewünschte Ergebnis "E G 3b". Gibt jedoch "e g 3b".title()zurück "E G 3B".
Sören
7
Denken Sie daran, dass dies auch dies verursachen wird:In [2]: 'tEst'.title() Out[2]: 'Test'
Jonas Libbrecht
4
Eine großartige Antwort und Kommentare zeigen, dass sich in Python nicht alles so verhält, wie Sie es brauchen, aber es gibt immer bequeme Möglichkeiten, dies zu erreichen. Der bequemste Weg ist oft das Importieren einer speziell erstellten Bibliothek, wie z. B. Python-Titlecase
Aaron3468
189

Die .title()Methode kann nicht gut funktionieren,

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

Versuchen Sie string.capwords()Methode,

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

Aus den Python-Dokumenten zu Capwords :

Teilen Sie das Argument mit str.split () in Wörter auf, schreiben Sie jedes Wort mit str.capitalize () groß und verbinden Sie die großgeschriebenen Wörter mit str.join (). Wenn das optionale zweite Argument sep fehlt oder None ist, werden Läufe von Leerzeichen durch ein einzelnes Leerzeichen ersetzt und führende und nachfolgende Leerzeichen entfernt. Andernfalls wird sep verwendet, um die Wörter zu teilen und zu verbinden.

Chen Houwu
quelle
2
Capwords fehlen noch und behandeln so etwas wie "There once was a string with an 'that had words right after it and then closed'". In diesem Beispiel werden alle Welten außer außer thatwie erwartet großgeschrieben. Die Ergebnisse sind"There Once Was A String With An 'that Had Words Right After It And Then Closed'"
Devonbleibtrey
Dies funktioniert jedoch besser als title()in normalen Situationen. In meiner Situation wird title()eine schlechte Ausgabe für Namen mit Akzenten oder Dieresis zurückgegeben, während capwords()sie korrekt behandelt wird.
Houcros
1
Gut, aber es bringt immer noch die Unterscheidung zwischen "Großbritannien und Großbritannien"
Jonath P,
1
@Chen Houwu, UK / UK ist ein perfektes Gegenbeispiel. Wie würde man Python daran hindern, vorhandene Großbuchstaben mit einer ähnlichen Methode zu verkleinern?
h0r53 vor
104

Nur weil mir so etwas Spaß macht, gibt es hier zwei weitere Lösungen.

In Wörter aufteilen, jedes Wort aus den aufgeteilten Gruppen mit einem Anfangsbuchstaben versehen und wieder verbinden. Dadurch wird der Leerraum, der die Wörter trennt, in einen einzelnen Leerraum geändert, unabhängig davon, um was es sich handelt.

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

EDIT: Ich erinnere mich nicht, was ich gedacht habe, als ich den obigen Code geschrieben habe, aber es besteht keine Notwendigkeit, eine explizite Liste zu erstellen. Wir können einen Generatorausdruck verwenden, um dies auf faule Weise zu tun. Also hier ist eine bessere Lösung:

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

Verwenden Sie einen regulären Ausdruck, der mit dem Anfang der Zeichenfolge übereinstimmt, oder Leerzeichen, die Wörter trennen, sowie ein einzelnes Nicht-Leerzeichen. Verwenden Sie Klammern, um "Übereinstimmungsgruppen" zu markieren. Schreiben Sie eine Funktion, die ein Übereinstimmungsobjekt verwendet und die Übereinstimmungsgruppe für Leerzeichen unverändert und die Übereinstimmungsgruppe für Nicht-Leerzeichen in Großbuchstaben zurückgibt. Verwenden Sie dann re.sub(), um die Muster zu ersetzen. Dieser hat weder die Interpunktionsprobleme der ersten Lösung, noch wiederholt er den Leerraum wie meine erste Lösung. Dieser liefert das beste Ergebnis.

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"

Ich bin froh, dass ich diese Antwort recherchiert habe. Ich hatte keine Ahnung, dass re.sub()das eine Funktion übernehmen könnte! Sie können im Inneren eine nicht triviale Verarbeitung durchführenre.sub() , um das Endergebnis zu erzielen!

steveha
quelle
1
+1 für die Lösung mit Scheiben. Ich brauchte etwas, das Großbuchstaben großschreibt, ohne die Großschreibung der restlichen Wörter zu ändern (z. B. wird Foo zu Foo, aber FOO wird zu FOO). Das war perfekt.
TomNysetvold
1
kapitalisieren gibt seinen ersten
großgeschriebenen
@ Vanuan, du hast recht! Die Beschreibung der Dokumentzeichenfolge ließ mich denken, dass nur der erste Buchstabe groß geschrieben wurde, aber Sie haben Recht damit, was er tatsächlich tut. Ich werde die Antwort bearbeiten. Danke für die Vorwarnung.
Steveha
Dies scheint das zu sein, was string.capwordslaut der Dokumentation in Chen Houwus Antwort geschieht.
Adrian Keister
1
In der obigen Antwort ist etwas zu beachten, anstatt s.split () zu verwenden. Ich denke, es ist besser, s.split ('') zu verwenden. Dies liegt daran, dass, falls die Zeichenfolge einige doppelte Leerzeichen enthält und Sie diese doppelten Leerzeichen beim Verbinden beibehalten möchten, s.plit ('') Ihnen dabei hilft, die Leerzeichen beizubehalten, während s.split () dies nicht
tut
21

Hier ist eine Zusammenfassung der verschiedenen Möglichkeiten, sie funktionieren für alle diese Eingaben:

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

- Die einfachste Lösung besteht darin, den Satz in Wörter aufzuteilen, den ersten Buchstaben groß zu schreiben und ihn dann wieder zusammenzufügen:

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

- Wenn Sie die Eingabezeichenfolge nicht zuerst in Wörter aufteilen und ausgefallene Generatoren verwenden möchten:

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

- Oder ohne itertools zu importieren:

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

- Oder Sie können reguläre Ausdrücke aus Steveas Antwort verwenden :

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

Dies sind einige andere Antworten , die veröffentlicht wurden, und Eingaben, für die sie nicht wie erwartet funktionieren, wenn wir die Definition eines Wortes als Satzanfang oder irgendetwas nach einem Leerzeichen verwenden:

  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"      

Wenn Sie '' für die Aufteilung verwenden, wird die zweite Ausgabe korrigiert, aber capwords () funktioniert für die erste immer noch nicht

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

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

Seien Sie vorsichtig mit mehreren Leerzeichen

  return ' '.join(w[0].upper() + w[1:] for w in s.split())
# Undesired outputs:
"foo    bar" => "Foo Bar"                 
aljgom
quelle
+1 für eine umfassende Zusammenfassung. Ich suche nach einer Möglichkeit, nur ein Wort nach einer Zahl (nicht jedes Wort) groß zu schreiben. Könnten Sie Ihre Antwort ergänzen, um dies zu demonstrieren? ZB lower 123 uppersollte zurückkehren lower 123 Upper, wo das uppergroß geschrieben wird, da es einer Zahl folgt. Ich weiß, dass dies über den Rahmen der OP-Frage hinausgeht, aber eine nette Ergänzung zu Ihrer bereits ausführlichen Antwort. Danke im Voraus.
ProGrammer
In diesem Fall können Sie einige der oben genannten Methoden an Ihre Anforderungen anpassen. Ich würde es jedoch nicht als Teil der Antwort hinzufügen, da es nicht das ist, wonach die meisten Leute suchen. Ich würde die Regex-Version dafür verwenden und "([0-9]+)(\s+.)"stattdessen "(^|\s)(\S)"(eine oder mehrere Zahlen, gefolgt von einem oder mehreren Leerzeichen und einem beliebigen "([0-9]+)(\s*.)"Zeichen danach ) verwenden oder wenn Sie das Zeichen nach 'null oder mehr' Leerzeichen nach dem Großbuchstaben großschreiben möchten Nummer
aljgom
Ich werde es mir sicher ansehen, was mich über einen anderen Sonderfall nachdenken ließ: Wie würden Sie die obigen Schnipsel so ändern, dass sie einen String nehmen, z. B. WW1 - the great warund WW1 - The Great Warstattdessen ausgeben Ww1 .... Sehen Sie das Problem mit Abkürzungen? Wären Sie bereit, etwas hinzuzufügen, das diesen Fall demonstriert? Ich habe mich schon eine Weile darüber gewundert und kann mir keinen Weg vorstellen, dies zu tun.
ProGrammer
Die ersten oben genannten Möglichkeiten ändern keine Buchstaben, die bereits in der Eingabezeichenfolge groß geschrieben wurden, und werden daher WW1alsWW1
aljgom
15

Copy-Paste-Ready-Version von @jibberia antwort:

def capitalize(line):
    return ' '.join(s[:1].upper() + s[1:] for s in line.split(' '))
Konstantin Spirin
quelle
2
Sie müssen keine Liste erstellen. str.joinakzeptiert Generatoren.
Warvariuc
@warvariuc Wie würden Sie diesen Code ändern, um Generatoren zu nutzen?
Konstantin Spirin
1
Entfernen Sie einfach die eckigen Klammern, wie es hier gemacht wird
warvariuc
1
Obwohl @warvariuc perfekt ist, um zu erwähnen, dass es joingen exps akzeptiert str.join, wird es im Allgemeinen besonders bevorzugt, ein Listenverständnis zu verwenden. Dies liegt daran, dass joindas Argument zweimal durchlaufen wird und es daher schneller ist, eine sofort einsatzbereite Liste als einen Generator bereitzustellen.
Bhargav Rao
1
@ BhargavRao, warum sollte str.joindas Argument zweimal wiederholt werden müssen? Ich habe nur nachgesehen - das tut es nicht. Bei kleinen Sequenzen ist das Listenverständnis in der Tat schneller.
Warvariuc
12

Warum erschweren Sie Ihr Leben mit Joins und for-Loops, wenn die Lösung einfach und sicher ist?

Mach das einfach:

string = "the brown fox"
string[0].upper()+string[1:]
Brad Larson
quelle
2
Weil es mehrere Wörter geben kann.
Arnaud
1
Ja, aber oft möchte ich nur den ersten Buchstaben groß schreiben. Dies ist ein Weg, dies zu tun.
Deleet
1
Würdest du dann nicht einfach benutzen "the brown fox".capitalize()?
Luckydonald
2
@luckydonald Denn vielleicht will ich nicht drehen 'this is John'in 'This is john'.
Januar 37
Ist kein besserer Weg, dies einfach zu tun string.capitalize()(im Wesentlichen Echo @luckydonald)
Hassan Baig
10

Wenn str.title () für Sie nicht funktioniert, führen Sie die Großschreibung selbst durch.

  1. Teilen Sie die Zeichenfolge in eine Liste von Wörtern
  2. Großschreiben Sie den ersten Buchstaben jedes Wortes
  3. Verbinden Sie die Wörter zu einer einzigen Zeichenfolge

Einzeiler:

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

Klares Beispiel:

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)
Jibberia
quelle
1
Ein interessanter Punkt bei dieser Lösung ist, dass Sie spezielle Leerzeichen verlieren. Je nach Kontext möglicherweise nicht wichtig.
mklauber
8

Wenn Sie nur den ersten Buchstaben wollen:

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

Aber um jedes Wort groß zu schreiben:

>>> 'hello world'.title()
'Hello World'
Zahran
quelle
Vorsicht, weil 'hello New York'.capitalize()ist'Hello new york'
user2314737
5

Eine leere Zeichenfolge löst einen Fehler aus, wenn Sie auf [1:] zugreifen. Daher würde ich Folgendes verwenden:

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

nur den ersten Buchstaben in Großbuchstaben schreiben.

Wim Feijen
quelle
Ist das nicht was str.capitalize?
Eugene Pakhomov
4
@Eugene, ja, aber leider Großbuchstaben alle anderen Buchstaben großschreiben, die möglicherweise nicht wünschenswert sind. : /
Wim Feijen
return title[:1].upper() + title[1:]würde sich auch um dieses Problem kümmern, da das Schneiden der leeren Zeichenfolge auf diese Weise 2 leere Zeichenfolgen ergeben würde, die zusammengefügt werden und eine leere Zeichenfolge ergeben, die zurückgegeben wird
aljgom
3

Wie Mark betonte, sollten Sie verwenden .title():

"MyAwesomeString".title()

Wenn Sie jedoch den ersten Buchstaben in einer Django-Vorlage in Großbuchstaben schreiben möchten , können Sie Folgendes verwenden:

{{ "MyAwesomeString"|title }}

oder mit einer Variablen:

{{ myvar|title }}
Chuckfinley
quelle
3

Die vorgeschlagene Methode str.title () funktioniert nicht in allen Fällen. Zum Beispiel:

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

anstatt "A B 3c" .

Ich denke, es ist besser, so etwas zu tun:

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'
Sören
quelle
1
Ein Fehler kann jedoch auftreten, wenn die Anzahl der sie trennenden Leerzeichen nicht 1 beträgt. Als Referenz: Hackerrank-Problem
Divakar Rajesh
3

Obwohl alle Antworten bereits zufriedenstellend sind, werde ich versuchen, die 2 zusätzlichen Fälle zusammen mit allen vorherigen Fällen abzudecken.

wenn die Leerzeichen nicht einheitlich sind und Sie diese beibehalten möchten

string = hello    world i  am    here.

wenn nicht alle Zeichenfolgen von Alphabeten ausgehen

string = 1 w 2 r 3g

Hier können Sie dies verwenden

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

das wird dir geben

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

Ich hoffe das ist nicht überflüssig.

Amit Gupta
quelle
2
Vielen Dank, dass Sie den Fall ungleichmäßiger Räume hervorgehoben haben. Einige der obigen Antworten verwenden s.split () anstelle von s.split (''). Es ist wichtig zu beachten, dass bei ungleichmäßigen Räumen die Verwendung von s.split ('') sicherstellt, dass die ungleichmäßigen Räume beibehalten werden!
Nochmals vielen
Dies funktioniert perfekt für Wörter mit ungleichmäßigen Leerzeichen oder Wörter, die mit einer Ziffer beginnen. Danke :)
Amresh Giri
2

Wörter groß schreiben ...

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

@ Gary02127 Kommentar, unten Lösungsarbeitstitel mit Apostroph

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))
Tejas Panzer
quelle
Die Verwendung der vorhandenen Funktion ermöglicht eine schnelle Ausführung in Python.
Tejas Tank
Ich mag title () nicht besonders, da es keine Apostrophe behandelt. "Ich kann nicht sagen" .title () gibt "Ich kann nicht sagen"
Gary02127
@ Gary02127 Ich hatte Antwort aktualisiert, bitte werfen Sie einen Blick, funktionierte auch perfekt mit Ihrer Problemdomäne
Tejas Tank
1

Übersehen Sie nicht die Erhaltung des Leerraums. Wenn Sie verarbeiten möchten 'fred flinstone'und 'Fred Flinstone'stattdessen erhalten 'Fred Flinstone', haben Sie Ihren Leerraum beschädigt. Einige der oben genannten Lösungen verlieren Leerraum. Hier ist eine Lösung, die für Python 2 und 3 gut ist und Leerzeichen bewahrt.

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

Eine schnelle Funktion funktionierte für 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.
PADYMKO
quelle
0

Großschreibung von Zeichenfolgen mit ungleichmäßigen Leerzeichen

Nun, ich verstehe, dass dies eine alte Frage ist und wahrscheinlich die Antworten fast erschöpft sind, aber ich möchte @Amit Guptas Punkt ungleichmäßiger Räume ergänzen. Von der ursprünglichen Frage möchten wir jedes Wort in der Zeichenfolge groß schreiben s = 'the brown fox'. Was wäre, wenn die Zeichenfolge s = 'the brown fox'ungleichmäßige Leerzeichen hätte ?

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)
Manpikin
quelle
.. Ihr Code kann Tabs nicht kompensieren, wenn es keine Leerzeichen zwischen Braun und Fuchs gibt ;-)
ZF007
-1

** Falls Sie verkleinern möchten **

 #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
Fouad Djebbar
quelle
-2

Diese Antwort gefällt mir sehr gut:

Copy-Paste-Ready-Version von @jibberia antwort:

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

Aber einige der Zeilen, die ich gesendet habe, haben einige leere Zeichen abgespalten, die beim Versuch, s [1:] auszuführen, Fehler verursacht haben. Es gibt wahrscheinlich einen besseren Weg, dies zu tun, aber ich musste ein if len (s)> 0 hinzufügen, wie in

return ' '.join([s[0].upper() + s[1:] for s in line.split(' ') if len(s)>0])
user1475777
quelle
2
Das ist zu kompliziert, wenn Sie überhaupt die Länge überprüfen?! ineffizient.