Ответы:
.title()Метод строки (ASCII или UNICODE штрафа) делает это:
>>> "hello world".title()
'Hello World'
>>> u"hello world".title()
u'Hello World'
Однако обратите внимание на строки со встроенными апострофами, как отмечено в документации.
Алгоритм использует простое независимое от языка определение слова как группы последовательных букв. Определение работает во многих контекстах, но оно означает, что апострофы в сокращениях и притяжениях образуют границы слов, что может не соответствовать желаемому результату:
>>> "they're bill's friends from the UK".title() "They'Re Bill'S Friends From The Uk"
"e g 3b"желаемый результат будет "E G 3b". Однако "e g 3b".title()возвращается "E G 3B".
In [2]: 'tEst'.title() Out[2]: 'Test'
.title()Метод не может хорошо работать,
>>> "they're bill's friends from the UK".title()
"They'Re Bill'S Friends From The Uk"
Попробуй string.capwords()метод,
import string
string.capwords("they're bill's friends from the UK")
>>>"They're Bill's Friends From The Uk"
Из документации по питону на заглавных словах :
Разбейте аргумент на слова с помощью str.split (), используйте каждое слово с заглавной буквы с помощью str.capitalize () и объедините слова с заглавными буквами с помощью str.join (). Если необязательный второй аргумент sep отсутствует или отсутствует, последовательности пробельных символов заменяются одним пробелом, а начальные и конечные пробелы удаляются, в противном случае sep используется для разделения и объединения слов.
"There once was a string with an 'that had words right after it and then closed'". В этом примере все миры, за исключением thatзаглавных, как и ожидалось. Результаты были"There Once Was A String With An 'that Had Words Right After It And Then Closed'"
title()в обычных ситуациях. В моей ситуации title()возвращает неверный вывод для имен с акцентом или диерезисом, при этом capwords()обрабатывается правильно.
Просто потому, что мне это нравится, вот еще два решения.
Разделите на слова, начальное заглавие каждого слова из разделенных групп и воссоединиться. Это изменит пробел, разделяющий слова на один пробел, независимо от того, что это было.
s = 'the brown fox'
lst = [word[0].upper() + word[1:] for word in s.split()]
s = " ".join(lst)
РЕДАКТИРОВАТЬ: я не помню, о чем я думал, когда писал вышеупомянутый код, но нет необходимости создавать явный список; мы можем использовать выражение генератора, чтобы сделать это ленивым способом. Итак, вот лучшее решение:
s = 'the brown fox'
s = ' '.join(word[0].upper() + word[1:] for word in s.split())
Используйте регулярное выражение для сопоставления начала строки или пробела, разделяющего слова, плюс один непробельный символ; используйте круглые скобки, чтобы пометить «группы соответствия». Напишите функцию, которая принимает объект сопоставления и возвращает группу совпадений с пробелами без изменений и группу сопоставления непробельных символов в верхнем регистре. Затем используйте re.sub()для замены шаблонов. У этого нет проблем пунктуации первого решения, и при этом это не переделывает пробел как мое первое решение. Этот дает лучший результат.
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"
Я рад, что исследовал этот ответ. Я понятия не имел, что re.sub()может взять на себя функцию! Вы можете сделать нетривиальную обработку внутри, re.sub()чтобы получить конечный результат!
string.capwords, что делает, согласно документации в ответе Чэнь Хоуу.
Вот краткое изложение различных способов сделать это, они будут работать для всех этих входных данных:
"" => ""
"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"
- Самое простое решение - разделить предложение на слова и использовать заглавную букву, а затем соединить его вместе:
# 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(' '))
- Если вы не хотите сначала разбивать входную строку на слова и использовать необычные генераторы:
# 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)) )
- Или без импорта itertools:
def cap_sentence(s):
return ''.join( (c.upper() if i == 0 or s[i-1] == ' ' else c) for i, c in enumerate(s) )
- Или вы можете использовать регулярные выражения из ответа Стивехи :
# 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)
Теперь, это некоторые другие ответы, которые были опубликованы, и входные данные, для которых они не работают должным образом, если мы используем определение слова, являющегося началом предложения или чего-либо после пробела:
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"
использование '' для разбиения исправит второй вывод, но capwords () все равно не будет работать для первого
return ' '.join(w.capitalize() for w in s.split(' '))
# or
import string
return string.capwords(s, ' ')
# Undesired outputs:
"foO baR" => "Foo Bar"
Будьте осторожны с несколькими пробелами
return ' '.join(w[0].upper() + w[1:] for w in s.split())
# Undesired outputs:
"foo bar" => "Foo Bar"
lower 123 upperдолжно возвращаться lower 123 Upper, где upperзаглавная, как следует за числом. Я знаю, что это выходит за рамки вопроса ОП, но является хорошим дополнением к вашему уже обширному ответу. Заранее спасибо.
"([0-9]+)(\s+.)"вместо "(^|\s)(\S)"(совпадение с одним или несколькими числами, после которых следуют один или несколько пробелов и любой символ после), или "([0-9]+)(\s*.)"если вы хотите использовать символ с большой буквы после пробела «ноль или более» после число
WW1 - the great warи вывели WW1 - The Great Warвместо Ww1 .... Видите проблему с сокращениями? Хотели бы вы добавить что-то, что демонстрирует этот случай? Я долго размышлял об этом и не могу придумать, как это сделать.
WW1выводятся какWW1
Готовая к копированию и вставке версия @jibberia anwser:
def capitalize(line):
return ' '.join(s[:1].upper() + s[1:] for s in line.split(' '))
str.joinпринимает генераторы.
joinпринимает gen exps, в str.joinчастности, обычно предпочтительнее использовать понимание списка. Это связано с тем, joinчто аргумент проходит дважды по аргументу, и, следовательно, быстрее создать готовый список, а не генератор.
str.joinнужно дважды повторять аргумент? Я только что проверил - это не так. Хотя для небольших последовательностей понимание списка действительно быстрее.
Почему вы усложняете свою жизнь соединениями и циклами, когда решение простое и безопасное?
Просто сделай это:
string = "the brown fox"
string[0].upper()+string[1:]
"the brown fox".capitalize()?
'this is John'в 'This is john'.
string.capitalize()(по сути, повторяя @luckydonald)
Если str.title () не работает для вас, сделайте капитализацию самостоятельно.
Один лайнер:
>>> ' '.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"
Наглядный пример:
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)
Если только вы хотите первую букву:
>>> 'hello world'.capitalize()
'Hello world'
Но, чтобы извлечь выгоду из каждого слова:
>>> 'hello world'.title()
'Hello World'
'hello New York'.capitalize()это'Hello new york'
Пустая строка вызовет ошибку, если вы получите доступ к [1:], поэтому я бы использовал:
def my_uppercase(title):
if not title:
return ''
return title[0].upper() + title[1:]
в верхнем регистре только первая буква.
str.capitalize?
return title[:1].upper() + title[1:]также позаботился бы об этой проблеме, так как разрезание пустой строки, как это, дало бы 2 пустые строки, соединенные вместе, чтобы создать пустую строку, которая возвращается
Как отметил Марк, вы должны использовать .title():
"MyAwesomeString".title()
Однако, если вы хотите сделать первую букву заглавной в шаблоне django , вы можете использовать это:
{{ "MyAwesomeString"|title }}
или используя переменную:
{{ myvar|title }}
Предложенный метод str.title () работает не во всех случаях. Например:
string = "a b 3c"
string.title()
> "A B 3C"
вместо "A B 3c".
Я думаю, что лучше сделать что-то вроде этого:
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'
Хотя все ответы уже удовлетворительные, но я постараюсь охватить 2 дополнительных случая вместе со всем предыдущим.
если пространства не одинаковы, и вы хотите сохранить то же самое
string = hello world i am here.
если все строки не начинаются с алфавитов
string = 1 w 2 r 3g
Здесь вы можете использовать это
def solve(s):
a = s.split(' ')
for i in range(len(a)):
a[i]= a[i].capitalize()
return ' '.join(a)
это даст вам
output = Hello World I Am Here
output = 1 W 2 R 3g
Я надеюсь, что это не избыточно.
Чтобы использовать слова ...
str = "this is string example.... wow!!!";
print "str.title() : ", str.title();
@ Gary02127 комментарий, ниже название работы решения с апострофом
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))
Не забывайте о сохранении пустого пространства. Если вы хотите обработать, 'fred flinstone'и вы получите 'Fred Flinstone'вместо 'Fred Flinstone', вы испортили пустое пространство. Некоторые из вышеуказанных решений потеряют пустое пространство. Вот решение, которое хорошо для Python 2 и 3 и сохраняет пустое пространство.
def propercase(s):
return ''.join(map(''.capitalize, re.split(r'(\s+)', s)))
Быстрая функция работала для Python 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.
Строка с заглавными буквами с неравномерными пробелами
Ну, я понимаю, что это старый вопрос, и, возможно, ответы на него, возможно, были почти исчерпаны, но я хотел бы добавить к точке @Amit Gupta неравномерных пространств. Исходя из исходного вопроса, мы хотели бы использовать каждое слово в строке с большой буквы s = 'the brown fox'. Что делать, если строка была s = 'the brown fox'с неоднородными пробелами.
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)
** В случае, если вы хотите уменьшить **
#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
Мне очень нравится этот ответ:
Готовая к копированию и вставке версия @jibberia anwser:
def capitalize(line):
return ' '.join([s[0].upper() + s[1:] for s in line.split(' ')])
Но некоторые строки, которые я отправлял, отделяли некоторые пустые символы '', которые вызывали ошибки при попытке сделать s [1:]. Вероятно, есть лучший способ сделать это, но мне пришлось добавить в if len (s)> 0, как в
return ' '.join([s[0].upper() + s[1:] for s in line.split(' ') if len(s)>0])
" ".join(w.capitalize() for w in s.split())