Есть ли способ использовать .title()
для получения правильного вывода из заголовка с апострофами? Например:
"john school".title() --> "John School"
Как мне получить правильный заголовок здесь, "John School"
?
Есть ли способ использовать .title()
для получения правильного вывода из заголовка с апострофами? Например:
"john school".title() --> "John School"
Как мне получить правильный заголовок здесь, "John School"
?
Если ваши заголовки не содержат нескольких пробельных символов в строке (которые будут свернуты), вы можете вместо этого использовать string.capwords():
>>> import string
>>> string.capwords("john school")
"John School"
РЕДАКТИРОВАТЬ: Как справедливо говорит Крис Морган ниже, вы можете устранить проблему с обвальным пробелом, указав " "
в аргументе sep
:
>>> string.capwords("john school", " ")
"John School"
Это сложно в общем случае, потому что некоторые отдельные апострофы законно следуют заглавным символом, таким как ирландские имена, начинающиеся с "O". string.capwords() будет работать во многих случаях, но игнорирует что-либо в кавычках. string.capwords( "john main говорит," нет ") не вернет результат, который вы ожидаете.
>>> capwords("John School")
"John School"
>>> capwords("john principal says,'no'")
"John Principal Says,'no'"
>>> capwords("John O'brien School")
"John O'brien School"
Более раздражающая проблема заключается в том, что сам титул не дает правильных результатов. Например, в американском использовании английский, статьи и предлоги обычно не капитализируются в заголовках или заголовках. (Чикагское руководство по стилю).
>>> capwords("John clears school of spiders")
'John Clears School Of Spiders'
>>> "John clears school of spiders".title()
'John Clears School Of Spiders'
>>> titlecase("John clears school of spiders")
'John Clears School of Spiders'
Я думаю, что это может быть сложно с title()
Давайте попробуем что-то другое:
def titlize(s):
b = []
for temp in s.split(' '): b.append(temp.capitalize())
return ' '.join(b)
titlize("john school")
// You get : John School
Надеюсь, что это поможет..!!
Хотя другие ответы полезны и более кратки, вы можете столкнуться с некоторыми проблемами с ними. Например, если в строке есть новые строки или вкладки. Кроме того, в некоторых случаях могут быть проблемы с переносимыми словами (с регулярными или неразрывными дефисами), а также с словами, начинающимися с апострофов. Однако, используя регулярные выражения (используя функцию для аргумента замены регулярного выражения), вы можете решить эти проблемы:
import re
def title_capitalize(match):
text=match.group()
i=0
new_text=""
capitalized=False
while i<len(text):
if text[i] not in {"’", "'"} and capitalized==False:
new_text+=text[i].upper()
capitalized=True
else:
new_text+=text[i].lower()
i+=1
return new_text
def title(the_string):
return re.sub(r"[\w'’‑-]+", title_capitalize, the_string)
s="here an apostrophe es. this string has multiple spaces\nnew\n\nlines\nhyphenated words: and non-breaking spaces, and a non‑breaking hyphen, as well as 'ords that begin with ’strophies; it\teven\thas\t\ttabs."
print(title(s))
В любом случае, вы можете отредактировать это, чтобы компенсировать любые дополнительные проблемы, такие как обратные ссылки и что-то-вы, если это необходимо.
Если вы считаете, что заголовок должен содержать такие предлоги, союзы и статьи в нижнем регистре, если они не находятся в начале или конце названия, вы можете попробовать такие, как этот код (но есть несколько двусмысленных слова, которые вам нужно выяснить по контексту, например when
):
import re
lowers={'this', 'upon', 'altogether', 'whereunto', 'across', 'between', 'and', 'if', 'as', 'over', 'above', 'afore', 'inside', 'like', 'besides', 'on', 'atop', 'about', 'toward', 'by', 'these', 'for', 'into', 'beforehand', 'unlike', 'until', 'in', 'aft', 'onto', 'to', 'vs', 'amid', 'towards', 'afterwards', 'notwithstanding', 'unto', 'while', 'next', 'including', 'thru', 'a', 'down', 'after', 'with', 'afterward', 'or', 'those', 'but', 'whereas', 'versus', 'without', 'off', 'among', 'because', 'some', 'against', 'before', 'around', 'of', 'under', 'that', 'except', 'at', 'beneath', 'out', 'amongst', 'the', 'from', 'per', 'mid', 'behind', 'along', 'outside', 'beyond', 'up', 'past', 'through', 'beside', 'below', 'during'}
def title_capitalize(match, use_lowers=True):
text=match.group()
lower=text.lower()
if lower in lowers and use_lowers==True:
return lower
else:
i=0
new_text=""
capitalized=False
while i<len(text):
if text[i] not in {"’", "'"} and capitalized==False:
new_text+=text[i].upper()
capitalized=True
else:
new_text+=text[i].lower()
i+=1
return new_text
def title(the_string):
first=re.sub(r"[\w'’‑-]+", title_capitalize, the_string)
return re.sub(r"(^[\w'’‑-]+)|([\w'’‑-]+$)", lambda match : title_capitalize(match, use_lowers=False), first)
ИМХО, лучший ответ @Frédéric one. Но если у вас уже есть строка, разделенная на слова, и вы знаете, как string.capwords
заполняется, то вы можете избежать ненужного шага соединения:
def capwords(s, sep=None):
return (sep or ' ').join(
x.capitalize() for x in s.split(sep)
)
В результате вы можете просто сделать это:
# here my_words == ['word1', 'word2', ...]
s = ' '.join(word.capitalize() for word in my_words)