python em maiúscula apenas a primeira letra

179

Estou ciente .capitalize () coloca em maiúscula a primeira letra de uma seqüência de caracteres, mas e se o primeiro caractere for um número inteiro?

isto

1bob
5sandy

para isso

1Bob
5Sandy
user1442957
fonte

Respostas:

234

Se o primeiro caractere for um número inteiro, ele não maiúscula a primeira letra.

>>> '2s'.capitalize()
'2s'

Se você deseja a funcionalidade, retire os dígitos, você pode usar '2'.isdigit()para verificar cada caractere.

>>> s = '123sa'
>>> for i, c in enumerate(s):
...     if not c.isdigit():
...         break
... 
>>> s[:i] + s[i:].capitalize()
'123Sa'
Ali Afshar
fonte
5
e é isso que esta resposta faz, praticamente
njzk2
16
Eu usaria se c.isalpha () em vez de se não c.isdigit ()
njzk2
1
Jan-PhilipGehrcke, que é um exercício para o leitor. Você pode ver nesse caso, s nunca está vazio, é sempre '123sa': D
Ali Afshar
2
@ Jan-PhilipGehrcke: nesse caso, next((i for i,e in enumerate(test) if not e.isdigit()), '0')resolve-lo para o caso de string vazia
njzk2
5
Esta resposta não está correta. . capitalizetambém transformará outros caracteres para abaixar. De docs oficiais: "Return uma versão titlecased de S, palavras ou seja, início com caracteres em caixa título, todas as restantes personagens encaixotados têm minúsculas. "
karantan
246

Somente porque ninguém mais o mencionou:

>>> 'bob'.title()
'Bob'
>>> 'sandy'.title()
'Sandy'
>>> '1bob'.title()
'1Bob'
>>> '1sandy'.title()
'1Sandy'

No entanto, isso também daria

>>> '1bob sandy'.title()
'1Bob Sandy'
>>> '1JoeBob'.title()
'1Joebob'

ou seja, não apenas coloca em maiúscula o primeiro caractere alfabético. Mas então .capitalize()tem o mesmo problema, pelo menos nisso 'joe Bob'.capitalize() == 'Joe bob', então meh.

DSM
fonte
38

Isso é semelhante à resposta do @ Anon, pois mantém intacto o restante do caso da string, sem a necessidade do módulo re.

def sliceindex(x):
    i = 0
    for c in x:
        if c.isalpha():
            i = i + 1
            return i
        i = i + 1

def upperfirst(x):
    i = sliceindex(x)
    return x[:i].upper() + x[i:]

x = '0thisIsCamelCase'

y = upperfirst(x)

print(y)
# 0ThisIsCamelCase

Como o @Xan apontou, a função poderia usar mais verificação de erros (como verificar se x é uma sequência - no entanto, estou omitindo casos extremos para ilustrar a técnica)

Atualizado por comentário @normanius (obrigado!)

Graças a @GeoStoneMarten ao apontar que não respondi à pergunta! -fixed that

pinkwerks
fonte
2
Muito útil, mas precisa de um len(x) == 0ramo.
Xan
desde o python 2.5, o caso vazio ainda pode ser tratado em uma linha: return x[0].upper() + x[1:] if len(x) > 0 else x
danio 13/06
Resposta muito útil, porque capitalize& titleprimeiro minúscula a seqüência inteira e, em seguida, maiúscula apenas a primeira letra.
Jonas Libbrecht
5
Útil. Basta usar a[:1].upper() + a[1:], isso cuidará da caixa de len(X)==0canto.
Normanius
1
Bom trabalho, mas não funciona neste caso, porque esta função coloca em maiúscula apenas o primeiro caractere e o primeiro caracter é dígito, não texto. Você precisa dividir o numérico e o dígito antes de usar e associar o resultado neste caso.
GeoStoneMarten
13

Aqui está uma linha que maiúscula a primeira letra e deixa o caso de todas as letras subseqüentes:

import re

key = 'wordsWithOtherUppercaseLetters'
key = re.sub('([a-zA-Z])', lambda x: x.groups()[0].upper(), key, 1)
print key

Isso resultará em WordsWithOtherUppercaseLetters

Anon
fonte
4

Como visto aqui respondido por Chen Houwu, é possível usar o pacote de strings:

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

Eu vim com isso:

import re

regex = re.compile("[A-Za-z]") # find a alpha
str = "1st str"
s = regex.search(str).group() # find the first alpha
str = str.replace(s, s.upper(), 1) # replace only 1 instance
print str
Prasanth
fonte
1

Você pode substituir a primeira letra ( preceded by a digit) de cada palavra usando regex:

re.sub(r'(\d\w)', lambda w: w.group().upper(), '1bob 5sandy')

output:
 1Bob 5Sandy
Kenly
fonte
1

uma linha: ' '.join(sub[:1].upper() + sub[1:] for sub in text.split(' '))

Gürol Canbek
fonte
Eu acho que você quer dizer isso, não é? '' .Join (sub [: 1] .upper () + sub [1:] para a sub em text.split (' '))
Michael
Corrigido. Obrigado @Michael
Gürol Canbek