828 Stimmen

Wie kann ich den ersten Buchstaben eines jeden Wortes in einer Zeichenfolge groß schreiben?

s = 'the brown fox'

...hier etwas tun...

s sein sollte:

'The Brown Fox'

Wie lässt sich das am einfachsten bewerkstelligen?

1352voto

Mark Rushakoff Punkte 236626

Le site .title() Methode einer Zeichenkette (entweder ASCII oder Unicode ist in Ordnung) tut dies:

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

Achten Sie jedoch auf Zeichenfolgen mit eingebetteten Apostrophen, wie in der Dokumentation angegeben.

Der Algorithmus verwendet eine einfache, sprachunabhängige Definition eines Wortes als Gruppe von aufeinanderfolgenden Buchstaben. Diese Definition funktioniert in vielen Kontexten, aber sie bedeutet, dass Apostrophe in Zusammenziehungen und Possessiven Wortgrenzen bilden, was nicht unbedingt das gewünschte Ergebnis ist:

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

263voto

Chen Houwu Punkte 2311

Le site .title() Methode nicht gut funktionieren kann,

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

De la Python-Dokumentation zu capwords :

Das Argument wird mit str.split() in Wörter zerlegt, jedes Wort mit str.capitalize() großgeschrieben und die großgeschriebenen Wörter mit str.join() zusammengefügt. Wenn das optionale zweite Argument sep fehlt oder nicht vorhanden ist, werden Leerzeichen durch ein einzelnes Leerzeichen ersetzt und führende und nachfolgende Leerzeichen entfernt, andernfalls wird sep zum Trennen und Verbinden der Wörter verwendet.

129voto

steveha Punkte 70950

Und weil mir so etwas Spaß macht, hier noch zwei weitere Lösungen.

In Wörter aufteilen, jedes Wort aus den aufgeteilten Gruppen mit den Initialen versehen und wieder zusammenfügen. Dadurch wird der Leerraum, der die Wörter trennt, in einen einzigen Leerraum umgewandelt, unabhängig davon, was er vorher war.

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

EDIT: Ich weiß nicht mehr, was ich dachte, als ich den obigen Code schrieb, aber es ist nicht nötig, eine explizite Liste zu erstellen; wir können einen Generatorausdruck verwenden, um dies auf eine faule Art zu tun. Hier ist also 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, um den Anfang der Zeichenkette oder das Leerzeichen zwischen den Wörtern sowie ein einzelnes Zeichen ohne Leerzeichen zu finden; verwenden Sie Klammern, um "Übereinstimmungsgruppen" zu markieren. Schreiben Sie eine Funktion, die ein Abgleichsobjekt entgegennimmt und die Abgleichsgruppe für Leerzeichen unverändert und die Abgleichsgruppe für Zeichen ohne Leerzeichen in Großbuchstaben zurückgibt. Verwenden Sie dann re.sub() um die Muster zu ersetzen. Bei dieser Lösung gibt es weder die Probleme mit der Zeichensetzung wie bei der ersten Lösung, noch wird der Leerraum wiederhergestellt wie bei meiner ersten Lösung. Diese Lösung 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() könnte eine Funktion übernehmen! Sie können nicht-triviale Verarbeitungen innerhalb von re.sub() um das Endergebnis zu erzielen!

48voto

aljgom Punkte 6035

Hier eine Zusammenfassung der verschiedenen Möglichkeiten

sie werden für alle diese Eingaben funktionieren:

""           => ""       
"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 einzelne Wörter aufzuteilen, den ersten Buchstaben groß zu schreiben und sie 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 Eingabezeichenkette nicht erst in Wörter zerlegen und ausgefallene Generatoren verwenden wollen:

# 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 den Import von itertools:

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 verwenden, von steveha's Antwort :

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

Nun, dies sind einige andere Antworten und Eingaben, bei denen sie nicht wie erwartet funktionieren, wenn wir die Definition eines Wortes als Satzanfang oder etwas 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"      

Durch die Verwendung von ' ' für den Split wird die zweite Ausgabe korrigiert, aber capwords() funktioniert immer noch nicht für die erste Ausgabe

  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"

17voto

Konstantin Spirin Punkte 19144

Kopierfertige Version der Antwort von @jibberia:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X