Python capitaliza solo la primera letra

179

Sé que .capitalize () escribe en mayúscula la primera letra de una cadena, pero ¿qué pasa si el primer carácter es un entero?

esta

1bob
5sandy

a esto

1Bob
5Sandy
usuario1442957
fuente

Respuestas:

234

Si el primer carácter es un entero, no capitalizará la primera letra.

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

Si desea la funcionalidad, elimine los dígitos, puede usar '2'.isdigit()para verificar cada carácter.

>>> s = '123sa'
>>> for i, c in enumerate(s):
...     if not c.isdigit():
...         break
... 
>>> s[:i] + s[i:].capitalize()
'123Sa'
Ali Afshar
fuente
55
y eso es lo que hace esta respuesta, más o menos
njzk2
16
Me gustaría utilizar si c.isalpha () en lugar de, si no c.isdigit ()
njzk2
1
@ Jan-PhilipGehrcke que es un ejercicio para el lector. Puedes ver en ese caso, s nunca está vacío, siempre es '123sa': D
Ali Afshar
2
@ Jan-PhilipGehrcke: en cuyo caso, lo next((i for i,e in enumerate(test) if not e.isdigit()), '0')resuelve para el caso de la cadena vacía
njzk2
55
Esta respuesta no es correcta. . capitalizeTambién transformará otros caracteres para bajar. De los documentos oficiales: "Devuelve una versión de S con título, es decir, las palabras comienzan con caracteres de título, todos los caracteres restantes tienen minúscula " .
karantan
246

Solo porque nadie más lo ha mencionado:

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

Sin embargo, esto también daría

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

es decir, no solo capitaliza el primer carácter alfabético. Pero luego .capitalize()tiene el mismo problema, al menos en eso 'joe Bob'.capitalize() == 'Joe bob', así que meh.

DSM
fuente
38

Esto es similar a la respuesta de @ Anon en que mantiene el resto de la caja de la cadena intacta, sin la necesidad del 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 señaló @Xan, la función podría usar más verificación de errores (como verificar que x es una secuencia; sin embargo, estoy omitiendo casos extremos para ilustrar la técnica)

Actualizado por comentario de @normanius (¡gracias!)

Gracias a @GeoStoneMarten por señalar que no respondí la pregunta. -corregido eso

Pinkwerks
fuente
2
Muy útil, pero necesita una len(x) == 0rama.
Xan
desde python 2.5, la caja vacía todavía se puede manejar en una línea: return x[0].upper() + x[1:] if len(x) > 0 else x
danio
Respuesta muy útil, porque capitalize& titleprimero en minúscula toda la cadena y luego en mayúscula solo la primera letra.
Jonas Libbrecht
55
Útil. Solo use a[:1].upper() + a[1:], esto se encargará del len(X)==0caso de la esquina.
normanius
1
Buen trabajo pero no funciona para este caso porque esta función capitaliza solo el primer caracter y el primer caracter es dígito, no texto. Necesita dividir números y dígitos antes de usar y unir resultado en este caso.
GeoStoneMarten
13

Aquí hay una línea que pondrá en mayúscula la primera letra y dejará el caso de todas las letras siguientes:

import re

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

Esto resultará en WordsWithOtherUppercaseLetters

Luego
fuente
4

Como vemos aquí respondido por Chen Houwu, es posible usar el paquete de cadena:

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

Se me ocurrió esto:

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
fuente
1

Puede reemplazar la primera letra ( preceded by a digit) de cada palabra usando regex:

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

output:
 1Bob 5Sandy
Kenly
fuente
1

una línea: ' '.join(sub[:1].upper() + sub[1:] for sub in text.split(' '))

Gürol Canbek
fuente
Creo que te refieres a esto, ¿no? '' .join (sub [: 1] .upper () + sub [1:] para sub en text.split (''))
Michael
Corregido Gracias @Michael
Gürol Canbek