Réponses:
La .title()
méthode d'une chaîne (ASCII ou Unicode est très bien) fait ceci:
>>> "hello world".title()
'Hello World'
>>> u"hello world".title()
u'Hello World'
Cependant, recherchez les chaînes avec des apostrophes intégrées, comme indiqué dans la documentation.
L'algorithme utilise une définition simple indépendante de la langue d'un mot en tant que 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 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"
"e g 3b"
, le résultat souhaité serait "E G 3b"
. Cependant, "e g 3b".title()
revient "E G 3B"
.
In [2]: 'tEst'.title() Out[2]: 'Test'
La .title()
méthode ne fonctionne pas bien,
>>> "they're bill's friends from the UK".title()
"They'Re Bill'S Friends From The Uk"
Essayez la string.capwords()
méthode,
import string
string.capwords("they're bill's friends from the UK")
>>>"They're Bill's Friends From The Uk"
Depuis les documents python sur capwords :
Divisez l'argument en mots en utilisant str.split (), mettez en majuscule chaque mot en utilisant str.capitalize () et joignez les mots en majuscule en utilisant str.join (). Si le deuxième argument facultatif sep est absent ou Aucun, les séquences 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 diviser et joindre les mots.
"There once was a string with an 'that had words right after it and then closed'"
. Avec 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'"
title()
dans des situations normales. Dans ma situation, title()
retourne une mauvaise sortie pour les noms avec des accents ou une diérèse, tout en le capwords()
gérant correctement.
Juste parce que ce genre de chose est amusant pour moi, voici deux autres solutions.
Divisez en mots, initialisez chaque mot des groupes divisés et rejoignez. Cela changera l'espace blanc séparant les mots en un seul espace blanc, quel qu'il soit.
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 quand 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 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 des mots séparant les espaces blancs, plus un seul caractère non blanc; utilisez des parenthèses pour marquer les "groupes de correspondance". Écrivez une fonction qui prend un objet de correspondance et renvoie le groupe de correspondance des espaces blancs inchangé et le groupe de correspondance des 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 fait des recherches sur cette réponse. Je n'avais aucune idée que cela re.sub()
pourrait prendre une fonction! Vous pouvez faire un traitement non trivial à l'intérieur re.sub()
pour produire le résultat final!
string.capwords
cas, selon la documentation dans la réponse de Chen Houwu.
Voici un résumé des différentes façons 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 à diviser la phrase en mots et à mettre la première lettre en majuscule, puis à la recoller:
# 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 d'abord diviser la chaîne d'entrée en mots et utiliser 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 importer d'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 la 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, voici quelques autres réponses qui ont été publié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 phrase ou quoi que ce soit 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"
l'utilisation de '' pour la division 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"
Soyez prudent avec plusieurs espaces vides
return ' '.join(w[0].upper() + w[1:] for w in s.split())
# Undesired outputs:
"foo bar" => "Foo Bar"
lower 123 upper
devrait revenir lower 123 Upper
, où le upper
est en majuscule comme il suit un nombre. Je sais que cela dépasse la portée de la question du PO, mais c'est un complément intéressant à votre réponse déjà détaillée. Merci d'avance.
"([0-9]+)(\s+.)"
place de "(^|\s)(\S)"
(faire correspondre un ou plusieurs nombres, suivi d'un ou plusieurs espaces, et n'importe quel caractère après), ou "([0-9]+)(\s*.)"
si vous voulez mettre en majuscule le caractère après 'zéro ou plusieurs' espaces après le number
WW1 - the great war
et la sortie WW1 - The Great War
au lieu de Ww1 ...
. Voir le problème avec les abréviations? Seriez-vous prêt à ajouter quelque chose qui illustre ce cas? Je me pose des questions à ce sujet depuis un certain temps maintenant et je ne vois pas comment le faire.
WW1
sortiraient commeWW1
Version prête à copier-coller de @jibberia anwser:
def capitalize(line):
return ' '.join(s[:1].upper() + s[1:] for s in line.split(' '))
str.join
accepte les générateurs.
join
accepte les exps gen, dans le cas str.join
particulier, il est généralement préférable d'utiliser une compréhension de liste. En effet, il join
répète deux fois l'argument et il est donc plus rapide de fournir une liste prête à l'emploi plutôt qu'un générateur.
str.join
besoin de répéter deux fois l'argument? Je viens de vérifier - ce n'est pas le cas. Cependant, pour les petites séquences, la compréhension de la liste est en fait plus rapide.
Pourquoi compliquez-vous votre vie avec des jointures et des boucles alors que la solution est simple et sûre ??
Faites juste ceci:
string = "the brown fox"
string[0].upper()+string[1:]
"the brown fox".capitalize()
?
'this is John'
devenir 'This is john'
.
string.capitalize()
(en écho essentiellement à @luckydonald)
Si str.title () ne fonctionne pas pour vous, faites la capitalisation vous-même.
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)
Si seulement vous voulez la première lettre:
>>> 'hello world'.capitalize()
'Hello world'
Mais pour capitaliser chaque mot:
>>> 'hello world'.title()
'Hello World'
'hello New York'.capitalize()
est'Hello new york'
Une chaîne vide soulèvera 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 mettre en majuscule uniquement la première lettre.
str.capitalize
?
return title[:1].upper() + title[1:]
s'occuperait également de ce problème puisque trancher la chaîne vide comme cela donnerait 2 chaînes vides, réunies pour créer une chaîne vide qui est retournée
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 }}
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'
Bien que toutes les réponses soient déjà satisfaisantes, je vais essayer de couvrir les 2 cas supplémentaires ainsi que tous les cas précédents.
si les espaces ne sont pas uniformes et que vous souhaitez les conserver
string = hello world i am here.
si toute la chaîne ne commence pas par des alphabets
string = 1 w 2 r 3g
Ici, vous pouvez utiliser ceci
def solve(s):
a = s.split(' ')
for i in range(len(a)):
a[i]= a[i].capitalize()
return ' '.join(a)
cela vous donnera
output = Hello World I Am Here
output = 1 W 2 R 3g
J'espère que ce n'est pas redondant.
Pour mettre des mots en majuscules ...
str = "this is string example.... wow!!!";
print "str.title() : ", str.title();
@ Commentaire de Gary02127, sous le titre de travail de la solution 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))
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 des solutions ci-dessus perdront de l'espace blanc. Voici une solution qui convient à Python 2 et 3 et qui préserve l'espace blanc.
def propercase(s):
return ''.join(map(''.capitalize, re.split(r'(\s+)', s)))
Une fonction rapide a fonctionné pour 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.
Capitaliser la chaîne avec des espaces non uniformes
Eh bien, je comprends que c'est une vieille question et les réponses ont probablement presque été épuisées, mais je voudrais ajouter au point @Amit Gupta des espaces non uniformes. À partir de la question d'origine, nous aimerions mettre en majuscule chaque mot de la chaîne s = 'the brown fox'
. Et si la chaîne était s = 'the brown fox'
avec des espaces non uniformes.
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)
** Si vous souhaitez réduire la taille **
#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
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 provoquaient des erreurs lors de la tentative de s [1:]. Il y a probablement une meilleure façon de le faire, mais j'ai dû ajouter un si len (s)> 0, comme dans
return ' '.join([s[0].upper() + s[1:] for s in line.split(' ') if len(s)>0])
" ".join(w.capitalize() for w in s.split())