python zapisuje wielką literę tylko na pierwszą literę

179

Wiem, że .capitalize () zamienia pierwszą literę ciągu na wielką literę, ale co, jeśli pierwszy znak jest liczbą całkowitą?

to

1bob
5sandy

do tego

1Bob
5Sandy
user1442957
źródło

Odpowiedzi:

234

Jeśli pierwszy znak jest liczbą całkowitą, pierwsza litera nie zostanie zamieniona na wielką.

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

Jeśli chcesz mieć tę funkcjonalność, '2'.isdigit()usuń cyfry, możesz użyć do sprawdzenia każdego znaku.

>>> s = '123sa'
>>> for i, c in enumerate(s):
...     if not c.isdigit():
...         break
... 
>>> s[:i] + s[i:].capitalize()
'123Sa'
Ali Afshar
źródło
5
i tak właśnie działa ta odpowiedź
njzk2
16
Użyłbym raczej c.isalpha () niż gdyby nie c.isdigit ()
njzk2
1
@ Jan-PhilipGehrcke, czyli ćwiczenie dla czytelnika. Widać, że w tym przypadku s nigdy nie jest puste, zawsze jest to „123sa”: D
Ali Afshar
2
@ Jan-PhilipGehrcke: w takim przypadku next((i for i,e in enumerate(test) if not e.isdigit()), '0')rozwiązuje problem dla przypadku pustego ciągu
njzk2
5
Ta odpowiedź jest nieprawidłowa. . capitalizezmieni również inne znaki na niższe. Z oficjalnych dokumentów: „Zwróć wersję S w tytule, tj. Słowa zaczynają się od wielkich liter w tytule, wszystkie pozostałe znaki mają małe litery.
karantan
246

Tylko dlatego, że nikt inny o tym nie wspomniał:

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

Jednak to również dałoby

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

tzn. nie tylko zamienia się na wielką literę pierwszego znaku alfabetu. Ale potem .capitalize()ma ten sam problem, przynajmniej w tym 'joe Bob'.capitalize() == 'Joe bob', więc meh.

DSM
źródło
38

Jest to podobne do odpowiedzi @ Anon, ponieważ zachowuje resztę wielkości liter w postaci nienaruszonej, bez potrzeby stosowania modułu 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

Jak zauważył @Xan, funkcja może używać więcej sprawdzania błędów (na przykład sprawdzania, czy x jest sekwencją - jednak pomijam przypadki skrajne, aby zilustrować technikę)

Zaktualizowano komentarzem @normanius (dzięki!)

Dzięki @GeoStoneMarten za wskazanie, że nie odpowiedziałem na pytanie! - naprawiłem to

pinkwerks
źródło
2
Bardzo przydatne, ale potrzebuje len(x) == 0gałęzi.
Xan
od Pythona 2.5 pusta sprawa może być nadal obsługiwana w jednej linii: return x[0].upper() + x[1:] if len(x) > 0 else x
danio
Bardzo przydatna odpowiedź, ponieważ capitalize& titlenajpierw małą literą cały ciąg, a potem wielką tylko pierwszą literę.
Jonas Libbrecht
5
Przydatny. Po prostu użyj a[:1].upper() + a[1:], to zajmie się len(X)==0skrzynką narożną.
normanius
1
Dobra robota, ale nie działa w tym przypadku, ponieważ ta funkcja wykorzystuje tylko pierwszy znak, a pierwszy znak to cyfra, a nie tekst. W tym przypadku musisz podzielić liczbę i cyfrę przed użyciem i wynik połączenia.
GeoStoneMarten
13

Oto jedna linijka, która będzie wielką pierwszą literą i pozostawi wielkość wszystkich kolejnych liter:

import re

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

Spowoduje to WordsWithOtherUppercaseLetters

Zaraz
źródło
4

Jak widzę tutaj odpowiedź Chen Houwu, możliwe jest użycie pakietu string:

import string
string.capwords("they're bill's friends from the UK")
>>>"They're Bill's Friends From The Uk"
Fábio
źródło
1

Wymyśliłem to:

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
źródło
1

Możesz zamienić pierwszą literę ( preceded by a digit) każdego słowa za pomocą wyrażenia regularnego:

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

output:
 1Bob 5Sandy
Kenly
źródło
1

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

Gürol Canbek
źródło
Myślę, że masz na myśli to, prawda? '' .join (sub [: 1] .upper () + sub [1:] for sub in text.split (''))
Michael
Poprawione. Dzięki @Michael
Gürol Canbek