814 votes

Comment mettre en majuscule la première lettre de chaque mot d'une chaîne de caractères ?

s = 'the brown fox'

...faire quelque chose ici...

s devrait être :

'The Brown Fox'

Quel est le moyen le plus simple de le faire ?

1327voto

Mark Rushakoff Points 97350

Le site .title() d'une chaîne de caractères (ASCII ou Unicode) :

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

Cependant, faites attention aux chaînes de caractères contenant des apostrophes intégrées, comme indiqué dans la documentation.

L'algorithme utilise une définition simple, indépendante de la langue, selon laquelle un mot est constitué de groupes de lettres consécutives. Cette définition fonctionne dans de nombreux contextes, mais elle implique que les apostrophes dans les contractions et les possessifs forment des limites de mots, 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"

1 votes

Vous démontrez str.title() pas string.title() . Python 2 unicode.title() fait la même chose pour les chaînes unicode.

85 votes

J'évite le problème du possessif avec quelque chose comme " ".join(w.capitalize() for w in s.split())

5 votes

Ce n'est pas sûr pour la plupart des chaînes de caractères car tous les mots, même les possessifs, sont mis en majuscules.

260voto

Chen Houwu Points 321

Le site .title() ne peut pas fonctionner correctement,

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

De la Documentation Python sur les mots-clés :

Divise l'argument en mots à l'aide de str.split(), met en majuscules chaque mot à l'aide de str.capitalize(), et joint les mots en majuscules à l'aide de str.join(). Si le deuxième argument facultatif sep est absent ou nul, les séries de caractères d'espacement sont remplacées par un espace unique et les espaces de début et de fin sont supprimés, sinon sep est utilisé pour diviser et joindre les mots.

5 votes

Capwords fait toujours défaut et ne gère pas quelque chose comme "There once was a string with an 'that had words right after it and then closed'" . Dans cet exemple, tous les mondes, à l'exception de that sont capitalisés comme prévu. Les résultats étant "There Once Was A String With An 'that Had Words Right After It And Then Closed'"

3 votes

Pourtant, cela fonctionne mieux que title() pour les situations normales. Dans ma situation, title() renvoie une mauvaise sortie pour les noms avec accents ou tréma, tandis que capwords() l'a traité correctement.

5 votes

C'est bien, mais ça gâche encore la distinction "Uk/UK".

127voto

steveha Points 24808

Juste parce que ce genre de choses m'amuse, voici deux autres solutions.

Se diviser en mots, parapher chaque mot des groupes divisés, et se rejoindre. Cela transformera 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 plus à 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. 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 seul caractère sans espace blanc ; utilisez des parenthèses pour marquer les "groupes de correspondance". Écrivez une fonction qui prend un objet match et renvoie le groupe de correspondance des espaces blancs inchangé et le groupe de correspondance des caractères autres que les espaces blancs en majuscules. Utilisez ensuite re.sub() pour remplacer les motifs. Celle-ci n'a pas les problèmes de ponctuation de la première solution, et ne refait pas les espaces blancs comme ma première solution. Celle-ci donne 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 n'avais aucune idée que re.sub() pourrait prendre une fonction ! Vous pouvez effectuer des traitements non triviaux à l'intérieur re.sub() pour produire le résultat final !

3 votes

+1 pour la solution utilisant les tranches. J'avais besoin de quelque chose qui mette en majuscules les premières lettres sans modifier la majuscule du reste des mots (par exemple, Foo devient foo, mais FOO devient fOO). C'était parfait.

3 votes

Capitalize renvoie son premier caractère en majuscule et le reste en minuscule.

1 votes

@Vanuan, vous avez raison ! La description de la chaîne de caractères m'a fait penser que tout ce qu'il faisait était de mettre en majuscule la première lettre, mais vous avez raison sur ce qu'il fait réellement. Je vais modifier la réponse. Merci de m'avoir prévenu.

17voto

Konstantin Spirin Points 5347

Version copier-coller de la réponse de @jibberia :

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

2 votes

Pas besoin de construire une liste. str.join accepte les générateurs.

0 votes

@warvariuc comment modifieriez-vous ce code pour tirer parti des générateurs ?

1 votes

Il suffit d'enlever les crochets, comme il est fait ici

11voto

jibberia Points 153

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

  1. Diviser la chaîne de caractères en une liste de mots
  2. Mettez la première lettre de chaque mot en majuscule
  3. Assembler les mots en une seule chaîne

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

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

1 votes

Un point intéressant avec cette solution est que vous perdez tout espace spécial. Cela peut ne pas être important selon le contexte.

0 votes

Il convient de noter que cette méthode échoue si la phrase ou l'ensemble de mots à mettre en majuscules contient un mot à un seul caractère comme "a" ou "I".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X