2009-10-11 2 views

ответ

663

.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" 
+1

Вы демонстрируете 'str.title()', а не 'string.title()'. Python 2 'unicode.title()' делает то же самое для строк unicode. – u0b34a0f6ae

+27

Я избегаю притяжательной проблемы с чем-то вроде '." .join (w.capitalize() для w в s.split()) ' – mehtunguh

+2

это небезопасно для большинства строк, потому что каждое слово даже притяжательное получает верхний регистр. – 2014-08-29 10:14:49

77

Просто потому, что такого рода вещи это удовольствие для меня, вот два больше решений.

Разделите слова, запишите каждое слово из разделенных групп и присоединитесь. Это изменит пробел, разделяющий слова, на одно пустое пространство, независимо от того, что было.

s = 'the brown fox' 
lst = [word[0].upper() + word[1:] for word in s.split()] 
s = " ".join(lst) 

EDIT: Я не помню, о чем я думал, когда я писал код выше, но нет никакой необходимости строить поименный список; мы можем использовать выражение генератора, чтобы сделать это ленивым способом. Так вот это лучшее решение:

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(), чтобы получить окончательный результат!

+7

+1 для действительно приятного способа избежать ловушек 'title()' –

+0

+1 для решения с использованием срезов. Мне нужно было что-то, что могло бы загладить первые буквы без изменения капитализации остальных слов (например, Foo становится foo, но FOO становится fOO) .Это было идеально. – TomNysetvold

+1

capize возвращает свой первый символ, а остальные нижние – Vanuan

10

Если str.title() не работает для вас, сделайте капитализацию самостоятельно.

  1. Разделить строку в список слов
  2. заглавной первую букву каждого слова
  3. Присоединяйтесь слова в одну строку

Однострочник:

>>> ' '.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) 
+1

Один интересный объект с этим золем что вы теряете какие-либо специальные пробелы. Может не быть важным в зависимости от контекста. – mklauber

+0

Upvote для получения прав Великобритании, в этом контексте лучше, чем ключевые слова. –

12

копипаст готовый вариант @jibberia anwser:

def capitalize(line): 
    return ' '.join(s[:1].upper() + s[1:] for s in line.split(' ')) 
+1

Не нужно создавать список. 'str.join' принимает генераторы. – warvariuc

+0

@warvariuc Как бы вы изменили этот код, чтобы использовать генераторы? –

+1

Просто удалите квадратные скобки, как будто это сделано [здесь] (http://stackoverflow.com/a/1549983/248296) – warvariuc

133

метод 'название' не может хорошо работать,

>>> "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" 

От python docs on capwords:

Разделите аргумент на слова, используя str.split(), запишите каждое слово, используя str.capitalize(), и соедините заглавные слова, используя str.join(). Если необязательный второй аргумент sep отсутствует или None, пробелы пробельных символов заменяются одним пробелом, а удаленные пробелы ведущие и конечные удаляются, иначе sep используется для разделения и объединения слов.

+2

Ключевых слов по-прежнему не хватает и не обрабатывает что-то вроде '' Там некогда была строка с ", которая имела слова сразу после нее, а затем закрывалась" «'. В этом примере все миры, кроме «того», капитализируются, как и ожидалось. Результаты: «Когда-то была строка с символом», которая имела правильные слова после этого и затем закрывалась »« – devonbleibtrey

+0

Тем не менее, это работает лучше, чем 'title()' для нормальных ситуаций. В моей ситуации 'title()' возвращает плохой результат для имен с акцентами или dieresis, а 'capwords()' обрабатывал его правильно. – houcros

+0

Работает лучше, чем 'title()' –

-2

Мне очень нравится этот ответ:

копипаст готовый вариант @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]) 
+2

Это слишком сложно, ведь вы даже проверяете длину ?! неэффективен. – 2014-08-29 10:16:01

2

Капитализировать слова ...

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)) 
+0

Использование существующей функции обеспечивает быстрое выполнение в python. –

+0

Я не очень люблю титул(), так как он не обрабатывает апострофы. «Я не могу сказать» .title() дает «Я не могу сказать» – Gary02127

+0

@ Gary02127 У меня был обновленный ответ, пожалуйста, посмотрите, отлично работал с вашей проблемной областью –

2

Как Марк отметил, вы должны использовать .title():

"MyAwesomeString".title() 

Однако, если бы хотело сделать первую букву заглавной внутри шаблона Джанго, вы могли бы использовать это:

{{ "MyAwesomeString"|title }} 

или с использованием переменного:

{{ myvar|title }} 
9

Почему вы усложните жизнь с объединениями и для циклов, когда решение является простым и безопасным?

Просто сделай это:

string = "the brown fox" 
string[0].upper()+string[1:] 
+1

Потому что может быть несколько слов. – Arnaud

+0

Да, но часто я хочу использовать только первую букву. Это способ сделать это. – Deleet

+0

Не могли бы вы тогда использовать «коричневую лисицу» .capitalize() '? – luckydonald

2

Предложенный метод str.title() не работает во всех случаях. Например:

string = "a b 3c" 
string.title() 
> "A B 3C" 

вместо "A B 3c".

Я думаю, что лучше сделать что-то вроде этого:

def capitalize_words(string): 
    words = string.split() 
    return ' '.join([word.capitalize() for word in words]) 

capitalize_words(string) 
>'A B 3c' 
10

Вот краткое описание различных способов сделать это:

Самое простое решение разделить предложение на слова и запишите первую букву, затем присоедините ее вместе.

# 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)) 

или вы можете использовать регулярные выражения, от steveha's answer

# 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) 

Они будут работать на все эти входы:

""   => ""  
"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"  

Теперь, вот некоторые других ответов, которые были размещены, и входы, для которых они не работают как ожидаются, если мы используем определение слова, которое начало предложения или что-нибудь после того, как пустое место:

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"     
+0

+1 для всеобъемлющего резюме. Я ищу способ извлечь только слово из числа (не каждое слово). Не могли бы вы добавить дополнение к своему ответу, демонстрирующему это? Например. 'lower 123 upper' должен возвращать' lower 123 Upper', где 'upper' капитализируется так, как следует число. Я знаю, что это выходит за рамки вопроса OP, но является хорошим дополнением к вашему уже обширному ответу. Заранее спасибо. – ProGrammer

+0

Вы можете изменить некоторые из вышеуказанных методов в соответствии с вашими потребностями в этом случае. Тем не менее, я бы не добавил его в качестве части ответа, так как это не то, что большинство людей ищут. Я бы использовал для него версию регулярного выражения и использовал '' ([0-9] +) (\ s +.) "' Вместо '" (^ | \ s) (\ S) "' (совпадение с одним или несколькими номерами , за которым следует одно или несколько пробелов и любой символ после) или '' ([0-9] +) (\ s *.) ", если вы хотите заглавничать символ после пробелов« нуль или больше »после номера – aljgom

+0

Я обязательно буду изучать это, что заставило меня подумать о другом специальном случае: как бы вы изменили фрагменты выше, чтобы взять строку, например «WW1 - великая война» и выход «WW1 - Великая война» вместо «Ww1 ...». См. Проблему с аббревиатурами? Не могли бы вы добавить что-то, что демонстрирует этот случай? Некоторое время я размышлял об этом и не могу придумать, как это сделать. – ProGrammer

5

Пустая строка вызовет ошибку при доступе к [1:], поэтому я бы использовал:

def my_uppercase(title): 
    if not title: 
     return '' 
    return title[0].upper() + title[1:] 

в верхний регистр только первая буква.

+0

Разве это не то, для чего предназначен 'str.capitalize'? –

+2

@ Юджин, да, но, к сожалению, заглавные буквы прочеркивают все другие буквы, которые могут быть нежелательны. :/ –

+0

'return title [: 1] .upper() + title [1:]' также позаботится об этой проблеме, так как нарезка пустой строки, подобной этой, даст две пустые строки, объединив их, сделав пустую строку, которая возвращается – aljgom

1

Не забывайте о сохранении пробелов. Если вы хотите обработать 'fred flinstone', и вы получите 'Fred Flinstone' вместо 'Fred Flinstone', вы испортили свое свободное пространство. Некоторые из вышеперечисленных решений потеряют пустое пространство.Вот решение, которое хорошо подходит для Python 2 и 3 и сохраняет пустое пространство.

def propercase(s): 
    return ''.join(map(''.capitalize, re.split(r'(\s+)', s))) 
0

Если только вы хотите первую букву: 'привет world'.capitalize() Выход: Привет мир

Но капитализировать каждое слово: ' привет world'.title() Выход: Привет, мир

 Смежные вопросы

  • Нет связанных вопросов^_^