Comment capitaliser la première lettre de chaque mot dans une chaîne (Python)?

s = 'the brown fox'

... faites quelque chose ici...

s devrait être :

'The Brown Fox'

Quelle est la meilleure façon de faire ça?

438
demandé sur Brad 2009-10-11 06:03:54

15 réponses

la .title() méthode d'une chaîne (soit ASCII ou Unicode est fine) fait ceci:

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

cependant, recherchez les chaînes à apostrophes incrustées, comme noté dans les docs.

l'algorithme utilise une définition simple et indépendante du langage d'un mot comme groupe de lettres consécutives. La définition fonctionne dans de nombreux contextes mais cela signifie que l'apostrophe dans les contractions et possessives forme mots limites, qui peuvent ne pas être le résultat souhaité:

>>> "they're bill's friends from the UK".title()
"They'Re Bill'S Friends From The Uk"
745
répondu Mark Rushakoff 2009-10-11 13:45:01

Le .title() méthode ne peut pas bien fonctionner,

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

Essayer string.capwords() la méthode,

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

De la python docs sur capwords :

Split l'argument en mots à l'aide str.split (), capitaliser chaque mot en utilisant str.capitaliser (), et joindre les mots en majuscules en utilisant str.rejoindre.)( Si le second argument optionnel sep est absent ou Aucun, les séries de caractères blancs sont remplacés par un espace unique et les espaces blancs menant et traînant sont supprimés, sinon sep est utilisé pour diviser et joindre les mots.

152
répondu Chen Houwu 2018-07-04 18:07:45

juste parce que ce genre de chose est amusant pour moi, voici deux autres solutions.

divisé en mots, initialiser chaque mot des groupes de scission, et de rejoindre. Cela changera l'espace blanc séparant les mots en un seul espace blanc, peu importe ce qu'il était.

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

EDIT: je ne me souviens pas de ce que je pensais quand j'ai écrit le code ci-dessus, mais il n'est pas nécessaire de construire une liste explicite; nous pouvons utilisez une expression de générateur pour le faire de façon paresseuse. Voici donc une meilleure solution:

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

utilisez une expression régulière pour faire correspondre le début de la chaîne, ou l'espace blanc séparant les mots, plus un caractère unique non-Espace; utilisez des parenthèses pour marquer"match groups". Ecrire une fonction qui prend un objet match, et renvoie le groupe de match espace blanc inchangé et le groupe de match caractère non-espace en majuscules. Ensuite, utilisez re.sub() pour remplacer les motifs. Celui-ci n'a pas les problèmes de ponctuation de la première solution, et il ne refait pas l'espace blanc comme ma première solution. Ce que l'on produit le meilleur résultat.

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"

je suis content d'avoir cherché cette réponse. Je ne savais pas que re.sub() pouvait prendre une fonction! Vous pouvez faire un traitement non trivial à l'intérieur de re.sub() pour produire le résultat final!

85
répondu steveha 2012-12-03 06:25:30

version prête à copier-coller de @jibberia anwser:

def capitalize(line):
    return ' '.join(s[:1].upper() + s[1:] for s in line.split(' '))
13
répondu Konstantin Spirin 2017-11-12 09:23:47

pourquoi compliquez-vous votre vie avec des jointures et pour des boucles alors que la solution est simple et sûre??

faites Simplement ceci:

string = "the brown fox"
string[0].upper()+string[1:]
11
répondu Brad Larson 2014-08-30 15:15:51

Si str.titre () ne fonctionne pas pour vous, faites la capitalisation vous-même.

  1. divise la chaîne en une liste de mots
  2. capitaliser la première lettre de chaque mot
  3. Joignez-vous aux mots dans une chaîne unique

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"

exemple clair:

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)
10
répondu jibberia 2009-10-11 06:05:41

Voici un résumé des différentes façons de le faire:

la solution la plus simple est de diviser la phrase en mots et de capitaliser la première lettre puis de la joindre à nouveau ensemble.

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

si vous ne voulez pas diviser la chaîne d'entrée en mots d'abord, et en utilisant des générateurs de fantaisie:

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

ou sans importation d'outils itératifs

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

ou vous pouvez utiliser expressions régulières, de réponse de 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)

ceux-ci fonctionneront pour toutes ces entrées:

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

maintenant, ce sont quelques autres réponses qui ont été affichés, et les entrées pour lesquelles ils ne fonctionnent pas comme prévu si nous utilisons la définition d'un mot étant le début de la phrase ou quelque chose après un espace vide:

  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"      

en utilisant '' pour le split fixera la deuxième sortie, mais capwords () ne fonctionnera toujours pas pour la première

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

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

faites attention avec plusieurs espaces vides

  return ' '.join(w[0].upper() + w[1:] for w in s.split())
# Undesired outputs:
"foo    bar" => "Foo Bar"                 
10
répondu aljgom 2018-01-07 22:03:52

une chaîne vide va soulever une erreur si vous accédez [1:], donc j'utiliserais:

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

pour majuscules la première lettre seulement.

5
répondu Wim Feijen 2018-01-10 16:14:35

comme Mark a indiqué que vous devez utiliser .title() :

"MyAwesomeString".title()

cependant, si vous souhaitez faire la première lettre majuscule à l'intérieur d'un modèle django , vous pouvez utiliser ceci:

{{ "MyAwesomeString"|title }}

ou en utilisant une variable:

{{ myvar|title }}
2
répondu chuckfinley 2014-03-16 13:04:49

La méthode suggérée str.titre() ne fonctionne pas dans tous les cas. Par exemple:

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

au lieu de "A B 3c" .

je pense que c'est mieux de faire quelque chose comme ça:

def capitalize_words(string):
    words = string.split()
    return ' '.join([word.capitalize() for word in words])

capitalize_words(string)
>'A B 3c'
2
répondu Sören 2016-11-11 17:57:17

pour capitaliser les mots...

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

@Gary02127 commentaire, ci-dessous la solution de travail titre avec 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))
2
répondu Tejas Tank 2018-01-07 09:33:37

ne négligez pas la préservation de l'espace blanc. Si vous voulez traiter 'fred flinstone' et que vous obtenez 'Fred Flinstone' au lieu de 'Fred Flinstone' , vous avez corrompu votre espace blanc. Certaines de ces solutions vont perdre de l'espace blanc. Voici une solution qui est bonne pour Python 2 et 3 et préserve l'espace blanc.

def propercase(s):
    return ''.join(map(''.capitalize, re.split(r'(\s+)', s)))
1
répondu Gary02127 2017-12-30 21:08:36

si seulement vous voulez la première lettre: 'bonjour le monde'.capitaliser() Sortie: Bonjour tout le monde

mais pour capitaliser chaque mot: 'bonjour le monde'.intitulé() Sortie: Bonjour tout le monde

1
répondu Zahran 2018-02-04 21:11:18

**Dans le cas où vous souhaitez réduire la taille de **

 #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
0
répondu Fouad Djebbar 2018-03-14 08:44:42

j'aime vraiment cette réponse:

version prête à copier-coller de @jibberia anwser:

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

mais certaines des lignes que j'envoyais séparaient des caractères Vierges qui causaient des erreurs en essayant de faire s[1:]. Il y a probablement une meilleure façon de le faire, mais j'ai dû ajouter un if len (s)>0, comme dans

return ' '.join([s[0].upper() + s[1:] for s in line.split(' ') if len(s)>0])
-2
répondu user1475777 2016-11-11 10:41:57