Respostas:
O .title()
método de uma sequência de caracteres (ASCII ou Unicode é bom) faz isso:
>>> "hello world".title()
'Hello World'
>>> u"hello world".title()
u'Hello World'
No entanto, procure seqüências de caracteres com apóstrofos incorporados, conforme observado nos documentos.
O algoritmo usa uma definição simples e independente de idioma de uma palavra como grupos de letras consecutivas. A definição funciona em muitos contextos, mas significa que apóstrofos em contrações e possessivos formam limites de palavras, o que pode não ser o resultado desejado:
>>> "they're bill's friends from the UK".title() "They'Re Bill'S Friends From The Uk"
"e g 3b"
, o resultado desejado seria "E G 3b"
. No entanto, "e g 3b".title()
retorna "E G 3B"
.
In [2]: 'tEst'.title() Out[2]: 'Test'
O .title()
método não pode funcionar bem,
>>> "they're bill's friends from the UK".title()
"They'Re Bill'S Friends From The Uk"
Tente string.capwords()
método,
import string
string.capwords("they're bill's friends from the UK")
>>>"They're Bill's Friends From The Uk"
Nos documentos python sobre capwords :
Divida o argumento em palavras usando str.split (), coloque cada letra em maiúscula usando str.capitalize () e junte as palavras em maiúscula usando str.join (). Se o segundo argumento opcional sep estiver ausente ou None, as execuções de caracteres de espaço em branco serão substituídas por um único espaço e os espaços em branco à esquerda e à direita serão removidos; caso contrário, sep será usado para dividir e unir as palavras.
"There once was a string with an 'that had words right after it and then closed'"
. Neste exemplo, todos os mundos, exceto os, that
são capitalizados conforme o esperado. Os resultados são #"There Once Was A String With An 'that Had Words Right After It And Then Closed'"
title()
em situações normais. Na minha situação, title()
retorna uma saída incorreta para nomes com acentos ou dieresis, enquanto capwords()
manipulada corretamente.
Só porque esse tipo de coisa é divertido para mim, aqui estão mais duas soluções.
Divida em palavras, limpe cada palavra dos grupos de divisão e junte-se novamente. Isso mudará o espaço em branco que separa as palavras em um único espaço em branco, não importa o que fosse.
s = 'the brown fox'
lst = [word[0].upper() + word[1:] for word in s.split()]
s = " ".join(lst)
EDIT: Não me lembro do que estava pensando quando escrevi o código acima, mas não há necessidade de criar uma lista explícita; podemos usar uma expressão geradora para fazê-lo de forma preguiçosa. Então, aqui está uma solução melhor:
s = 'the brown fox'
s = ' '.join(word[0].upper() + word[1:] for word in s.split())
Use uma expressão regular para corresponder ao início da sequência, ou espaço em branco que separa as palavras, além de um caractere que não seja um espaço em branco; use parênteses para marcar "grupos de correspondência". Escreva uma função que pegue um objeto de correspondência e retorne o grupo de correspondência de espaços em branco inalterado e o grupo de correspondência de caracteres que não sejam espaços em branco em maiúsculas. Em seguida, use re.sub()
para substituir os padrões. Este não possui os problemas de pontuação da primeira solução, nem refaz o espaço em branco como minha primeira solução. Este produz o melhor resultado.
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"
Estou feliz por ter pesquisado esta resposta. Eu não tinha ideia de que re.sub()
poderia ter uma função! Você pode fazer um processamento não trivial dentro re.sub()
para produzir o resultado final!
string.capwords
acontece, de acordo com a documentação na resposta de Chen Houwu.
Aqui está um resumo das diferentes maneiras de fazer isso, elas funcionarão para todas essas entradas:
"" => ""
"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"
- A solução mais simples é dividir a frase em palavras e colocar em maiúscula a primeira letra e depois juntá-la novamente:
# 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 você não deseja dividir a sequência de entrada em palavras primeiro, e usando geradores sofisticados:
# 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 sem importar ferramentas:
def cap_sentence(s):
return ''.join( (c.upper() if i == 0 or s[i-1] == ' ' else c) for i, c in enumerate(s) )
- Ou você pode usar expressões regulares, a partir da resposta 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)
Agora, estas são algumas outras respostas que foram postadas e entradas para as quais elas não funcionam conforme o esperado, se estivermos usando a definição de uma palavra que é o início da frase ou qualquer coisa depois de um espaço em branco:
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"
usar '' para a divisão corrigirá a segunda saída, mas capwords () ainda não funcionará pela primeira
return ' '.join(w.capitalize() for w in s.split(' '))
# or
import string
return string.capwords(s, ' ')
# Undesired outputs:
"foO baR" => "Foo Bar"
Tenha cuidado com vários espaços em branco
return ' '.join(w[0].upper() + w[1:] for w in s.split())
# Undesired outputs:
"foo bar" => "Foo Bar"
lower 123 upper
deve retornar lower 123 Upper
, onde o upper
é capitalizado como segue um número. Sei que vai além do escopo da pergunta do OP, mas é um bom complemento para a sua já extensa resposta. Desde já, obrigado.
"([0-9]+)(\s+.)"
vez de "(^|\s)(\S)"
(corresponder a um ou mais números, seguidos de um ou mais espaços e qualquer caractere depois), ou "([0-9]+)(\s*.)"
se você quiser colocar o caractere em maiúscula após 'zero ou mais' espaços após o número
WW1 - the great war
e output em WW1 - The Great War
vez de Ww1 ...
. Veja o problema com abreviações? Você gostaria de adicionar algo que demonstre esse caso? Eu estive pensando sobre isso por um tempo agora e não consigo pensar em uma maneira de fazê-lo.
WW1
seriam WW1
Versão pronta para copiar e colar do @jibberia anwser:
def capitalize(line):
return ' '.join(s[:1].upper() + s[1:] for s in line.split(' '))
str.join
aceita geradores.
join
aceita gen exps, no caso de str.join
particularmente, geralmente é preferível usar uma lista de compreensão. Isso ocorre porque join
itera duas vezes sobre o argumento e, portanto, é mais rápido fornecer uma lista pronta para uso em vez de um gerador.
str.join
precisaria repetir duas vezes sobre o argumento? Acabei de verificar - não. Embora para pequenas sequências a compreensão da lista seja mais rápida.
Por que você complica sua vida com junções e loops quando a solução é simples e segura?
Apenas faça o seguinte:
string = "the brown fox"
string[0].upper()+string[1:]
"the brown fox".capitalize()
?
'this is John'
em 'This is john'
.
string.capitalize()
(@luckydonald essencialmente ecoando)
Se str.title () não funcionar, faça você mesmo a capitalização.
Uma linha:
>>> ' '.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"
Exemplo claro:
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)
Se você quiser apenas a primeira letra:
>>> 'hello world'.capitalize()
'Hello world'
Mas para capitalizar cada palavra:
>>> 'hello world'.title()
'Hello World'
'hello New York'.capitalize()
é'Hello new york'
Uma string vazia gerará um erro se você acessar [1:]; portanto, eu usaria:
def my_uppercase(title):
if not title:
return ''
return title[0].upper() + title[1:]
para maiúsculas apenas a primeira letra.
str.capitalize
é para isso que serve?
return title[:1].upper() + title[1:]
também cuidar desse problema, já que cortar a cadeia vazia como o que daria 2 cadeias vazias, unidas fazer uma cadeia vazia, que é devolvido
Como Mark apontou, você deve usar .title()
:
"MyAwesomeString".title()
No entanto, se você quiser colocar a primeira letra em maiúscula dentro de um modelo de django , você pode usar o seguinte:
{{ "MyAwesomeString"|title }}
ou usando uma variável:
{{ myvar|title }}
O método sugerido str.title () não funciona em todos os casos. Por exemplo:
string = "a b 3c"
string.title()
> "A B 3C"
em vez de "A B 3c"
.
Eu acho que é melhor fazer algo assim:
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'
Embora todas as respostas já sejam satisfatórias, tentarei cobrir os dois casos extras, juntamente com o caso anterior.
se os espaços não forem uniformes e você quiser manter o mesmo
string = hello world i am here.
se toda a cadeia não estiver começando no alfabeto
string = 1 w 2 r 3g
Aqui você pode usar isso
def solve(s):
a = s.split(' ')
for i in range(len(a)):
a[i]= a[i].capitalize()
return ' '.join(a)
isso vai te dar
output = Hello World I Am Here
output = 1 W 2 R 3g
Espero que isso não seja redundante.
Para capitalizar palavras ...
str = "this is string example.... wow!!!";
print "str.title() : ", str.title();
@ Gary02127 comentário, abaixo do título do trabalho da solução com apóstrofo
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))
Não negligencie a preservação do espaço em branco. Se você deseja processar 'fred flinstone'
e obtém, em 'Fred Flinstone'
vez de 'Fred Flinstone'
, danificou seu espaço em branco. Algumas das soluções acima perderão espaço em branco. Aqui está uma solução que é boa para Python 2 e 3 e preserva o espaço em branco.
def propercase(s):
return ''.join(map(''.capitalize, re.split(r'(\s+)', s)))
Uma função rápida funcionou para 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.
Colocar letras maiúsculas em maiúsculas com espaços não uniformes
Bem, eu entendo que essa é uma pergunta antiga e provavelmente as respostas podem estar quase esgotadas, mas eu gostaria de acrescentar ao ponto de espaços não uniformes do @Amit Gupta. A partir da pergunta original, gostaríamos de capitalizar todas as palavras da string s = 'the brown fox'
. E se a string estivesse s = 'the brown fox'
com espaços não 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)
** Caso você queira reduzir o tamanho **
#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
Eu realmente gosto desta resposta:
Versão pronta para copiar e colar do @jibberia anwser:
def capitalize(line):
return ' '.join([s[0].upper() + s[1:] for s in line.split(' ')])
Mas algumas das linhas que eu estava enviando separavam alguns caracteres em branco '' que causavam erros ao tentar fazer s [1:]. Provavelmente existe uma maneira melhor de fazer isso, mas eu tive que adicionar um if len (s)> 0, como em
return ' '.join([s[0].upper() + s[1:] for s in line.split(' ') if len(s)>0])
" ".join(w.capitalize() for w in s.split())