Odpowiedzi:
.title()Metoda łańcucha znaków (ASCII lub Unicode jest w porządku) to robi:
>>> "hello world".title()
'Hello World'
>>> u"hello world".title()
u'Hello World'
Należy jednak zwrócić uwagę na ciągi znaków z osadzonymi apostrofami, jak zauważono w dokumentacji.
Algorytm wykorzystuje prostą, niezależną od języka definicję słowa jako grupy kolejnych liter. Definicja działa w wielu kontekstach, ale oznacza, że apostrofy w skurczach i dzierżawczy tworzą granice słów, co może nie być pożądanym rezultatem:
>>> "they're bill's friends from the UK".title() "They'Re Bill'S Friends From The Uk"
"e g 3b"pożądany wynik będzie "E G 3b". Jednak "e g 3b".title()powraca "E G 3B".
In [2]: 'tEst'.title() Out[2]: 'Test'
.title()Metoda nie może działać dobrze,
>>> "they're bill's friends from the UK".title()
"They'Re Bill'S Friends From The Uk"
Wypróbuj string.capwords()metodę
import string
string.capwords("they're bill's friends from the UK")
>>>"They're Bill's Friends From The Uk"
Z dokumentacji Pythona na temat haseł :
Podziel argument na słowa za pomocą str.split (), wielkie litery każdego słowa za pomocą str.capitalize () i połącz wielkie litery za pomocą str.join (). Jeśli opcjonalny drugi argument sep jest nieobecny lub Brak, przebiegi białych znaków są zastępowane pojedynczą spacją, a wiodące i końcowe białe spacje są usuwane, w przeciwnym razie sep służy do dzielenia i łączenia słów.
"There once was a string with an 'that had words right after it and then closed'". W tym przykładzie wszystkie światy z wyjątkiem thatsą kapitalizowane zgodnie z oczekiwaniami. Rezultat jest"There Once Was A String With An 'that Had Words Right After It And Then Closed'"
title()w normalnych sytuacjach. W mojej sytuacji title()zwraca zły wynik dla nazw z akcentami lub dieresis, gdy jest capwords()obsługiwany poprawnie.
Tylko dlatego, że tego rodzaju zabawa sprawia mi przyjemność, oto dwa kolejne rozwiązania.
Podziel na słowa, napisz początkowo każde słowo z podzielonych grup i dołącz ponownie. Spowoduje to zmianę białej przestrzeni oddzielającej słowa na jedną białą spację, bez względu na to, co to było.
s = 'the brown fox'
lst = [word[0].upper() + word[1:] for word in s.split()]
s = " ".join(lst)
EDYCJA: Nie pamiętam, o czym myślałem, kiedy pisałem powyższy kod, ale nie ma potrzeby budowania wyraźnej listy; możemy użyć wyrażenia generatora, aby zrobić to leniwie. Oto lepsze rozwiązanie:
s = 'the brown fox'
s = ' '.join(word[0].upper() + word[1:] for word in s.split())
Użyj wyrażenia regularnego, aby dopasować początek łańcucha lub spacji oddzielających słowa, a także pojedynczego znaku spacji; użyj nawiasów, aby zaznaczyć „dopasuj grupy”. Napisz funkcję, która pobiera obiekt dopasowania i zwraca niezmienioną grupę dopasowań białych znaków oraz grupę dopasowań znaków niebiałych dużymi literami. Następnie użyj, re.sub()aby zastąpić wzory. Ten nie ma problemów z interpunkcją pierwszego rozwiązania, ani nie przerabia białej przestrzeni jak moje pierwsze rozwiązanie. Ten daje najlepszy wynik.
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"
Cieszę się, że zbadałem tę odpowiedź. Nie miałem pojęcia, że re.sub()może przyjąć jakąś funkcję! Możesz wykonać nietrywialne przetwarzanie w re.sub()celu uzyskania ostatecznego rezultatu!
string.capwordsjest, zgodnie z dokumentacją zawartą w odpowiedzi Chen Houwu.
Oto podsumowanie różnych sposobów, aby to zrobić, będą działać dla wszystkich tych danych wejściowych:
"" => ""
"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"
- Najprostszym rozwiązaniem jest podzielenie zdania na słowa i zapisanie pierwszej litery wielką literą, a następnie połączenie jej z powrotem:
# 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(' '))
- Jeśli nie chcesz najpierw podzielić łańcucha wejściowego na słowa i używając fantazyjnych generatorów:
# 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)) )
- Lub bez importowania itertools:
def cap_sentence(s):
return ''.join( (c.upper() if i == 0 or s[i-1] == ' ' else c) for i, c in enumerate(s) )
- Lub możesz użyć wyrażeń regularnych z odpowiedzi Stevehy :
# 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)
Oto niektóre inne odpowiedzi, które zostały opublikowane, i dane wejściowe, dla których nie działają zgodnie z oczekiwaniami, jeśli używamy definicji słowa będącego początkiem zdania lub czegokolwiek po spacji:
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"
użycie '' do podziału naprawi drugie wyjście, ale capwords () nadal nie będzie działać dla pierwszego
return ' '.join(w.capitalize() for w in s.split(' '))
# or
import string
return string.capwords(s, ' ')
# Undesired outputs:
"foO baR" => "Foo Bar"
Uważaj na wiele pustych miejsc
return ' '.join(w[0].upper() + w[1:] for w in s.split())
# Undesired outputs:
"foo bar" => "Foo Bar"
lower 123 upperPowinien powrócić lower 123 Upper, gdzie upperlitera jest pisana wielkimi literami, ponieważ następuje po niej liczba. Wiem, że wykracza to poza zakres pytania PO, ale stanowi miły dodatek do już i tak obszernej odpowiedzi. Z góry dziękuję.
"([0-9]+)(\s+.)"zamiast tego "(^|\s)(\S)"(dopasuj jedną lub więcej liczb, a następnie jedną lub więcej spacji i dowolne "([0-9]+)(\s*.)"znaki po ), lub jeśli chcesz wstawić znak po „zerach lub więcej” spacji po liczba
WW1 - the great warI wyjście WW1 - The Great Warzamiast Ww1 .... Widzisz problem ze skrótami? Czy byłbyś skłonny dodać coś, co pokazuje ten przypadek? Zastanawiam się nad tym od dłuższego czasu i nie mogę wymyślić sposobu, aby to zrobić.
WW1będzie odtwarzany jakoWW1
Wersja @jibberia gotowa do skopiowania i wklejenia:
def capitalize(line):
return ' '.join(s[:1].upper() + s[1:] for s in line.split(' '))
str.joinakceptuje generatory.
joinakceptuje generacje, w str.joinszczególności szczególnie preferowane jest używanie listowania . Wynika to z tego, że joiniteruje się dwa razy w stosunku do argumentu, a zatem szybsze jest dostarczenie gotowej listy niż generatora.
str.jointrzeba powtarzać dwukrotnie argument? Właśnie sprawdziłem - nie ma. Jednak w przypadku małych sekwencji zrozumienie listy jest rzeczywiście szybsze.
Dlaczego komplikujesz swoje życie połączeniami i pętlami, gdy rozwiązanie jest proste i bezpieczne?
Po prostu zrób to:
string = "the brown fox"
string[0].upper()+string[1:]
"the brown fox".capitalize()?
'this is John'się 'This is john'.
string.capitalize()(zasadniczo echo @luckydonald)
Jeśli str.title () nie działa dla Ciebie, wykonaj wielkie litery sam.
Jednowarstwowy:
>>> ' '.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"
Jasny przykład:
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)
Jeśli tylko chcesz pierwszą literę:
>>> 'hello world'.capitalize()
'Hello world'
Ale wielkie litery każdego słowa:
>>> 'hello world'.title()
'Hello World'
'hello New York'.capitalize()to'Hello new york'
Pusty ciąg wywoła błąd, jeśli uzyskasz dostęp do [1:], dlatego użyłbym:
def my_uppercase(title):
if not title:
return ''
return title[0].upper() + title[1:]
tylko wielką pierwszą literą.
str.capitalizejest?
return title[:1].upper() + title[1:]będzie również dbać o ten problem, ponieważ krojenie pusty łańcuch tak dałoby 2 pustych strun, połączonych ze sobą zrobić pusty ciąg znaków, który jest zwracany
Jak zauważył Mark, powinieneś użyć .title():
"MyAwesomeString".title()
Jednak jeśli chcesz zrobić pierwszą literę w szablonie django , możesz użyć tego:
{{ "MyAwesomeString"|title }}
lub używając zmiennej:
{{ myvar|title }}
Sugerowana metoda str.title () nie działa we wszystkich przypadkach. Na przykład:
string = "a b 3c"
string.title()
> "A B 3C"
zamiast "A B 3c".
Myślę, że lepiej zrobić coś takiego:
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'
Chociaż wszystkie odpowiedzi są już zadowalające, ale postaram się objąć 2 dodatkowe przypadki wraz ze wszystkimi poprzednimi przypadkami.
jeśli spacje nie są jednolite i chcesz zachować to samo
string = hello world i am here.
jeśli cały ciąg nie zaczyna się od alfabetu
string = 1 w 2 r 3g
Tutaj możesz tego użyć
def solve(s):
a = s.split(' ')
for i in range(len(a)):
a[i]= a[i].capitalize()
return ' '.join(a)
to ci da
output = Hello World I Am Here
output = 1 W 2 R 3g
Mam nadzieję, że to nie jest zbędne.
Aby używać wielkich słów ...
str = "this is string example.... wow!!!";
print "str.title() : ", str.title();
@ Gary02127 komentarz, poniżej tytuł pracy rozwiązania z apostrofem
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))
Nie zapomnij o zachowaniu białej przestrzeni. Jeśli chcesz przetworzyć, 'fred flinstone'a 'Fred Flinstone'zamiast tego 'Fred Flinstone'dostajesz, uszkodziłeś swoją białą przestrzeń. Niektóre z powyższych rozwiązań utracą białe miejsca. Oto rozwiązanie, które jest dobre dla Python 2 i 3 i pozwala zachować białe znaki.
def propercase(s):
return ''.join(map(''.capitalize, re.split(r'(\s+)', s)))
Szybka funkcja działała w Pythonie 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.
Łańcuch należy pisać wielkimi niejednolitymi spacjami
Rozumiem, że to stare pytanie i prawdopodobnie odpowiedzi zostały prawie wyrzucone z równowagi, ale chciałbym dodać do punktu niejednolitych przestrzeni @Amit Gupta. Z pierwotnego pytania chcielibyśmy używać każdego słowa w ciągu s = 'the brown fox'. Co jeśli ciąg miał s = 'the brown fox'niejednolite spacje.
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)
** W przypadku, gdy chcesz zmniejszyć rozmiar **
#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
Naprawdę podoba mi się ta odpowiedź:
Wersja @jibberia gotowa do skopiowania i wklejenia:
def capitalize(line):
return ' '.join([s[0].upper() + s[1:] for s in line.split(' ')])
Ale niektóre wiersze, które wysyłałem, oddzielały puste znaki, które powodowały błędy podczas próby wykonania s [1:]. Prawdopodobnie jest na to lepszy sposób, ale musiałem dodać if len (s)> 0, jak w
return ' '.join([s[0].upper() + s[1:] for s in line.split(' ') if len(s)>0])
" ".join(w.capitalize() for w in s.split())