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

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'

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.


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


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


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"

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

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

1

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


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.