web-dev-qa-db-fra.com

Comment mettre en majuscule la première lettre de chaque mot d'une chaîne (Python)?

s = 'the brown fox'

... fais quelque chose ici ...

s devrait être:

'The Brown Fox'

Quelle est la façon la plus simple de faire cela?

464
TIMEX

La méthode .title() d'une chaîne (ASCII ou Unicode convient parfaitement) fait ceci:

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

Cependant, recherchez les chaînes avec des apostrophes incorporées, comme indiqué dans la documentation.

L'algorithme utilise une définition simple, indépendante du langage, d'un mot sous forme de groupes de lettres consécutives. La définition fonctionne dans de nombreux contextes mais cela signifie que les apostrophes dans les contractions et les possessifs forment des frontières de Word, ce qui peut ne pas être le résultat souhaité:

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

La méthode .title() ne fonctionne pas bien, 

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

Essayez string.capwords() méthode, 

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

À partir de python docs sur capwords :

Divisez l'argument en mots à l'aide de str.split (), mettez en majuscule chaque mot à l'aide de str.capitalize () et joignez les mots en majuscule à l'aide de str.join () Si le second argument facultatif sep est absent ou None, les séries de caractères d'espacement sont remplacées par un seul espace et les espaces de début et de fin sont supprimés. Sinon, sep est utilisé pour scinder et joindre les mots.

166
Chen Houwu

Juste parce que ce genre de chose est amusant pour moi, voici deux solutions supplémentaires.

Divisez en mots, initialisez chaque mot des groupes divisés et rejoignez-les. Cela changera l'espace blanc séparant les mots en un seul espace blanc, peu importe ce que c'é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 à quoi je pensais lorsque j'ai écrit le code ci-dessus, mais il n'est pas nécessaire de construire une liste explicite; nous pouvons utiliser une expression de générateur pour le faire de manière paresseuse. Alors voici 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 des mots séparant les espaces, plus un seul caractère non-blanc; utilisez des parenthèses pour marquer "groupes de correspondance". Ecrivez une fonction qui prend un objet de correspondance et retourne le groupe de correspondance d'espaces non modifié et le groupe de correspondance de caractères non-blancs en majuscules. Utilisez ensuite re.sub() pour remplacer les motifs. Celui-ci n'a pas les problèmes de ponctuation de la première solution, ni ne refait l'espace blanc comme ma première solution. Celui-ci 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 recherché cette réponse. Je n'avais aucune idée que re.sub() pourrait prendre une fonction! Vous pouvez effectuer un traitement non trivial dans re.sub() pour obtenir le résultat final!

89
steveha

Version prête à l'emploi de @jibberia anwser:

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

Voici un résumé des différentes manières de le faire, elles 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"     

- La solution la plus simple consiste à scinder la phrase en mots et à mettre la première lettre en majuscule, puis à la relier: 

# 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 scinder la chaîne d'entrée en mots en premier, et utilisez des générateurs 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 importer itertools:

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

Maintenant, ce sont quelques autres réponses qui ont été postées et des entrées pour lesquelles elles ne fonctionnent pas comme prévu si nous utilisons la définition d'un mot comme début de la phrase ou de tout ce qui suit un espace:

  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"      

utiliser '' pour la scission corrigera 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"      

Soyez prudent avec plusieurs espaces vides

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

Pourquoi compliquez-vous votre vie avec des jointures et des boucles lorsque la solution est simple et sûre ??

Faites juste ceci:

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

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

  1. Fractionner la chaîne en une liste de mots
  2. Mettre en majuscule la première lettre de chaque mot
  3. Joignez les mots en une seule chaîne

Bon mot:

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

Une chaîne vide générera une erreur si vous accédez à [1:], donc je voudrais utiliser:

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

mettre en majuscule la première lettre seulement.

5
Wim Feijen

Comme Mark l’a souligné, vous devez utiliser .title() :

"MyAwesomeString".title()

Cependant, si vous souhaitez mettre la première lettre en majuscule dans un modèle Django, vous pouvez utiliser ceci:

{{ "MyAwesomeString"|title }}

ou en utilisant une variable:

{{ myvar|title }}
3
chuckfinley

Pour capitaliser les mots ...

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

@ Gary02127 commentaire, titre de solution ci-dessous 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
Tejas Tank

La méthode suggérée str.title () 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 qu'il vaut mieux faire quelque chose comme ça:

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'
2
Sören

Ne négligez pas la préservation de l'espace blanc. Si vous souhaitez traiter 'fred flinstone' et que vous obtenez 'Fred Flinstone' au lieu de 'Fred Flinstone', vous avez corrompu votre espace blanc. Certaines des solutions ci-dessus vont perdre de l'espace. Voici une solution qui convient aux Python 2 et 3 et préserve les espaces.

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

Si seulement vous vouliez la première lettre: «Bonjour tout le monde». Capitalisation () Sortie:

Mais pour capitaliser chaque mot: 'Hello world'.title () Sortie:

1
Zahran

** Si vous souhaitez réduire les effectifs **

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