Ответы:
.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())