Come scrivere in maiuscolo la prima lettera di ogni parola in una stringa?


589
s = 'the brown fox'

... fai qualcosa qui ...

s dovrebbe essere :

'The Brown Fox'

Qual è il modo più semplice per farlo?

Risposte:


991

Il .title()metodo di una stringa (ASCII o Unicode va bene) fa questo:

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

Tuttavia, cerca le stringhe con apostrofi incorporati, come indicato nei documenti.

L'algoritmo utilizza una semplice definizione indipendente dal linguaggio di una parola come gruppi di lettere consecutive. La definizione funziona in molti contesti ma significa che gli apostrofi nelle contrazioni e nei possessivi formano confini di parole, che potrebbero non essere il risultato desiderato:

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

56
Evito il problema possessivo con qualcosa del genere" ".join(w.capitalize() for w in s.split())
mehtunguh,

3
questo non è sicuro per la maggior parte delle stringhe perché ogni parola anche possessiva viene maiuscola.

10
Si è verificato un problema con string.title (). Quando si utilizza, ad esempio "e g 3b", il risultato desiderato sarebbe "E G 3b". Tuttavia, "e g 3b".title()ritorna "E G 3B".
Sören,

7
Tieni presente che questo causerà anche questo:In [2]: 'tEst'.title() Out[2]: 'Test'
Jonas Libbrecht,

4
Ottima risposta e commenti evidenziano che in Python non tutto si comporta nel modo in cui è necessario, ma ci sono sempre modi convenienti per farlo. Il modo più conveniente è spesso importare una libreria appositamente costruita, come python-titlecase
Aaron3468

189

Il .title() metodo non può funzionare bene,

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

Provare string.capwords() metodo,

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

Dal documenti di Python su capwords :

Dividere l'argomento in parole usando str.split (), scrivere in maiuscolo ogni parola usando str.capitalize () e unire le parole in maiuscolo usando str.join (). Se il secondo argomento facoltativo sep è assente o Nessuno, le serie di caratteri di spazi bianchi vengono sostituite da uno spazio singolo e gli spazi bianchi iniziali e finali vengono rimossi, altrimenti sep viene utilizzato per dividere e unire le parole.


2
Mancano ancora le parole d'ordine e non gestisce qualcosa del genere "There once was a string with an 'that had words right after it and then closed'". Con questo esempio tutti i mondi tranne quelli thatsono capitalizzati come previsto. Il risultato è"There Once Was A String With An 'that Had Words Right After It And Then Closed'"
devonbleibtrey,

Tuttavia, funziona meglio rispetto title()alle situazioni normali. Nella mia situazione, title()restituisce un output negativo per i nomi con accenti o dieresi, mentre capwords()gestito correttamente.
houcros,

1
Bene, ma rovina ancora la distinzione "Regno Unito / Regno Unito"
Jonath P

1
@Chen Houwu, Regno Unito / Regno Unito è un contro esempio perfetto. Come si impedirebbe a Python di mettere in minuscolo le lettere maiuscole esistenti usando un metodo simile?
h0r53

105

Solo perché questo genere di cose è divertente per me, ecco altre due soluzioni.

Dividi in parole, sigla ogni parola dai gruppi divisi e ricongiungiti. Questo cambierà lo spazio bianco che separa le parole in un unico spazio bianco, non importa quale fosse.

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

EDIT: non ricordo cosa stavo pensando quando ho scritto il codice sopra, ma non è necessario creare un elenco esplicito; possiamo usare un'espressione generatrice per farlo in modo pigro. Quindi ecco una soluzione migliore:

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

Usa un'espressione regolare per abbinare l'inizio della stringa, o lo spazio bianco che separa le parole, più un singolo carattere non bianco; utilizzare le parentesi per contrassegnare "gruppi di corrispondenza". Scrivi una funzione che accetta un oggetto di corrispondenza e restituisce invariato il gruppo di corrispondenza degli spazi bianchi e il gruppo di corrispondenza dei caratteri non bianchi in maiuscolo. Quindi utilizzare re.sub()per sostituire i motivi. Questo non ha i problemi di punteggiatura della prima soluzione, né rifà lo spazio bianco come la mia prima soluzione. Questo produce il miglior risultato.

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"

Sono contento di aver cercato questa risposta. Non avevo idea che re.sub()potesse avere una funzione! È possibile eseguire elaborazioni non banali all'interno re.sub()per produrre il risultato finale!


1
+1 per la soluzione utilizzando le sezioni. Avevo bisogno di qualcosa che potesse mettere in maiuscolo le prime lettere senza alterare la maiuscola delle altre parole (ad esempio Foo diventa foo, ma FOO diventa fOO). Questo è stato perfetto
TomNysetvold,

1
capitalize restituisce il suo primo personaggio in maiuscolo e il resto in minuscolo
Vanuan

@Vanuan, hai ragione! La descrizione della stringa di documenti mi ha fatto pensare che tutto ciò che facesse fosse scrivere in maiuscolo la prima lettera, ma hai ragione su ciò che effettivamente fa. Modificherò la risposta. Grazie per l'heads-up.
Steveha,

Questo sembra essere ciò che string.capwordsfa, secondo la documentazione nella risposta di Chen Houwu.
Adrian Keister,

1
Qualcosa da notare nella risposta sopra, invece di usare s.split (), penso che sia meglio usare s.split (''). Questo perché nel caso in cui la stringa abbia degli spazi doppi e si desidera mantenere quegli spazi doppi durante l'unione, s.plit ('') ti aiuterà a mantenere gli spazi mentre s.split () non lo farà
manpikin,

21

Ecco un riepilogo di diversi modi per farlo, funzioneranno per tutti questi input:

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

- La soluzione più semplice è dividere la frase in parole e scrivere in maiuscolo la prima lettera, quindi ricollegarla:

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

- Se non vuoi prima dividere la stringa di input in parole e usare generatori elaborati:

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

- O senza importare itertools:

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

- Oppure puoi usare espressioni regolari, dalla risposta di 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)

Ora, queste sono alcune altre risposte che sono state pubblicate e input per i quali non funzionano come previsto se stiamo usando la definizione di una parola che è l'inizio della frase o qualcosa dopo uno spazio vuoto:

  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"      

l'uso di '' per la divisione risolverà il secondo output, ma capwords () non funzionerà ancora per il primo

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

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

Fai attenzione con più spazi vuoti

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

+1 per un riepilogo completo. Sto cercando un modo per scrivere in maiuscolo solo una parola che segue un numero (non tutte le parole). Potresti aggiungere una risposta alla tua dimostrazione di ciò? Ad esempio, lower 123 upperdovrebbe tornare lower 123 Upper, dove upperè in maiuscolo in quanto segue un numero. So che va oltre lo scopo della domanda del PO, ma un bel componente aggiuntivo alla tua già ampia risposta. Grazie in anticipo.
ProGrammer

In questo caso è possibile modificare alcuni dei metodi sopra indicati in base alle proprie esigenze. Tuttavia, non lo aggiungerei come parte della risposta poiché non è quello che la maggior parte delle persone sta cercando. Userei la versione regex per questo, e userei "([0-9]+)(\s+.)"invece di "(^|\s)(\S)"(abbina uno o più numeri, seguito da uno o più spazi, e qualsiasi carattere dopo), o "([0-9]+)(\s*.)"se vuoi mettere in maiuscolo il carattere dopo spazi 'zero o più' dopo il numero
aljgom

Sarò sicuro di esaminarlo, che mi ha fatto riflettere su un altro caso speciale: come modificheresti gli snippet sopra per prendere una stringa, ad esempio WW1 - the great ware output WW1 - The Great Warinvece di Ww1 .... Vedi il problema con le abbreviazioni? Saresti disposto ad aggiungere qualcosa che dimostri questo caso? Mi sto chiedendo da un po 'di tempo ormai e non riesco a pensare a un modo per farlo.
ProGrammer

I primi modi indicati sopra non cambiano le lettere che erano già in maiuscolo nella stringa di input, quindi WW1verrebbero emesse comeWW1
aljgom

15

Versione copia-incolla di @jibberia anwser:

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

2
Non è necessario creare un elenco. str.joinaccetta generatori.
Warvariuc,

@warvariuc come cambieresti questo codice per sfruttare i generatori?
Konstantin Spirin,

1
Basta rimuovere le parentesi quadre, come è fatto qui
warvariuc,

1
Sebbene @warvariuc sia perfetto nel menzionare che joinaccetta gen exps, nel caso in str.joinparticolare, è generalmente preferito usare una comprensione della lista. Questo perché joinscorre due volte l'argomento, quindi è più veloce fornire un elenco pronto anziché un generatore.
Bhargav Rao

1
@BhargavRao perché dovrebbe str.joinripetere due volte l'argomento? Ho appena controllato - non lo fa. Sebbene per le sequenze di piccole dimensioni la comprensione dell'elenco sia più rapida.
Warvariuc,

12

Perché complicate la vostra vita con join e loop quando la soluzione è semplice e sicura ??

Basta fare questo:

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

2
Perché possono esserci più parole.
Arnaud,

1
Sì, ma spesso voglio solo scrivere in maiuscolo la prima lettera. Questo è un modo per farlo.
Deleet,

1
Non useresti quindi "the brown fox".capitalize()?
luckydonald,

2
@luckydonald Perché forse non voglio trasformarmi 'this is John'in 'This is john'.
janek37,

Non è un modo migliore per farlo semplicemente string.capitalize()(essenzialmente riecheggiando @luckydonald)
Hassan Baig

10

Se str.title () non funziona per te, fai tu stesso le maiuscole.

  1. Dividi la stringa in un elenco di parole
  2. Scrivi in ​​maiuscolo la prima lettera di ogni parola
  3. Unisci le parole in un'unica stringa

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"

Chiaro esempio:

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
Un punto di interesse con questa soluzione è la perdita di spazi bianchi speciali. Potrebbe non essere importante a seconda del contesto.
mklauber,

8

Se solo tu vuoi la prima lettera:

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

Ma per capitalizzare ogni parola:

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

Attento perché 'hello New York'.capitalize()è'Hello new york'
user2314737

5

Una stringa vuota genererà un errore se accedi a [1:], quindi utilizzerei:

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

maiuscolo solo per la prima lettera.


Non è quello che str.capitalizeserve?
Eugene Pakhomov,

4
@Eugene, sì, ma sfortunatamente, le lettere maiuscole in maiuscolo potrebbero non essere desiderabili. : /
Wim Feijen,

return title[:1].upper() + title[1:]si occuperebbe anche di quel problema poiché tagliare la stringa vuota in quel modo darebbe 2 stringhe vuote, unite insieme per creare una stringa vuota che viene restituita
aljgom

3

Come ha sottolineato Mark, dovresti usare .title():

"MyAwesomeString".title()

Tuttavia, se si desidera rendere la prima lettera maiuscola all'interno di un modello django , è possibile utilizzare questo:

{{ "MyAwesomeString"|title }}

o usando una variabile:

{{ myvar|title }}

3

Il metodo suggerito str.title () non funziona in tutti i casi. Per esempio:

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

invece di "A B 3c".

Penso che sia meglio fare qualcosa del genere:

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
tuttavia potrebbe verificarsi un errore se il numero di spazi che li separano non è 1. Per riferimento: problema di hackerrank
Divakar Rajesh,

3

Sebbene tutte le risposte siano già soddisfacenti, ma proverò a coprire i 2 casi extra insieme a tutti i casi precedenti.

se gli spazi non sono uniformi e si desidera mantenere lo stesso

string = hello    world i  am    here.

se tutta la stringa non parte da alfabeti

string = 1 w 2 r 3g

Qui puoi usare questo

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

questo ti darà

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

Spero che questo non sia ridondante.


2
Grazie per aver evidenziato il caso di spazi non uniformi. Alcune risposte sopra usano s.split () invece di s.split (''). È importante notare che per gli spazi non uniformi, l'utilizzo di s.split ('') garantirà il mantenimento degli spazi non uniformi! Grazie ancora
manpikin

Funziona perfettamente con parole con spazi irregolari o parole che iniziano con una cifra. Grazie :)
Amresh Giri,

2

Per scrivere in maiuscolo ...

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

@ Commento Gary02127, sotto il titolo dell'opera soluzione con apostrofo

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

Usa la funzione esistente per un'esecuzione rapida in Python.
Tejas Tank,

Non mi piace molto il titolo (), dal momento che non gestisce gli apostrofi. "Non posso dire" .title () dà "Non posso dire"
Gary02127

@ Gary02127 Avevo una risposta aggiornata, per favore dai un'occhiata, ha funzionato perfettamente anche con il tuo dominio problematico
Tejas Tank

1

Non trascurare la conservazione dello spazio bianco. Se vuoi elaborare 'fred flinstone'e ottieni 'Fred Flinstone'invece di 'Fred Flinstone', hai corrotto il tuo spazio bianco. Alcune delle soluzioni di cui sopra perderanno spazi bianchi. Ecco una soluzione che va bene per Python 2 e 3 e conserva gli spazi bianchi.

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

0

Una funzione rapida ha funzionato per 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

Metti in maiuscolo la stringa con spazi non uniformi

Bene, capisco che questa è una vecchia domanda e probabilmente le risposte potrebbero essere state quasi esaurite, ma vorrei aggiungere al punto di @Amit Gupta degli spazi non uniformi. Dalla domanda originale, vorremmo scrivere in maiuscolo ogni parola nella stringa s = 'the brown fox'. E se la stringa fosse s = 'the brown fox'con spazi non uniformi.

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)

.. il tuo codice non riesce a compensare le schede se non è bianco tra brown e fox ;-)
ZF007

-1

** Nel caso in cui si desideri ridimensionare **

 #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

Mi piace molto questa risposta:

Versione copia-incolla di @jibberia anwser:

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

Ma alcune delle righe che stavo inviando dividevano alcuni caratteri '' vuoti che causavano errori quando provavo a fare s [1:]. Probabilmente esiste un modo migliore per farlo, ma ho dovuto aggiungere a if len (s)> 0, come in

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

2
Questo è eccessivamente complicato, con che cosa fai per controllare la lunghezza ?! inefficiente.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.