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 that
są 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.capwords
jest, 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 upper
Powinien powrócić lower 123 Upper
, gdzie upper
litera 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 war
I wyjście WW1 - The Great War
zamiast 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ć.
WW1
bę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.join
akceptuje generatory.
join
akceptuje generacje, w str.join
szczególności szczególnie preferowane jest używanie listowania . Wynika to z tego, że join
iteruje się dwa razy w stosunku do argumentu, a zatem szybsze jest dostarczenie gotowej listy niż generatora.
str.join
trzeba 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.capitalize
jest?
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())