Есть стандартный способ в Python для titlecase строки (т.е. слова начинаются с прописными буквами, все остальные символы имеют обсаженные в нижнем регистр) , но оставив статьи , как and
, in
и of
строчные?
Ответы:
С этим есть несколько проблем. Если вы используете разделение и соединение, некоторые символы пробела будут проигнорированы. Встроенные методы капитализации и заголовка не игнорируют пробелы.
>>> 'There is a way'.title()
'There Is A Way'
Если предложение начинается со статьи, вы не хотите, чтобы первое слово заголовка было в нижнем регистре.
Имея это в виду:
import re
def title_except(s, exceptions):
word_list = re.split(' ', s) # re.split behaves as expected
final = [word_list[0].capitalize()]
for word in word_list[1:]:
final.append(word if word in exceptions else word.capitalize())
return " ".join(final)
articles = ['a', 'an', 'of', 'the', 'is']
print title_except('there is a way', articles)
# There is a Way
print title_except('a whim of an elephant', articles)
# A Whim of an Elephant
str.split
не учитывает смежные пробелы. re.split
сохраняет пробелы. Итак, эта функция не занимает места.
"".split()
не считал их, но учел "".split(" ")
.
title_except('a whim of aN elephant', articles)
case. Вы можете использовать word.lower() in exceptions
условие фильтрации, чтобы исправить это.
2001 a Space Odyssey
должен вернуться 2001 A Space Odyssey
, где после a
числа следует заглавная буква. Заранее спасибо.
Используйте модуль titlecase.py ! Работает только на английском.
>>> from titlecase import titlecase
>>> titlecase('i am a foobar bazbar')
'I Am a Foobar Bazbar'
Вот такие методы:
>>> mytext = u'i am a foobar bazbar'
>>> print mytext.capitalize()
I am a foobar bazbar
>>> print mytext.title()
I Am A Foobar Bazbar
Вариантов артикля в нижнем регистре нет. Вам придется написать это самостоятельно, возможно, используя список статей, которые вы хотите сократить.
Стюарт Colville сделал порт Python из сценария Perl , написанной Джон Грубер , чтобы преобразовать строки в заголовке дела , но избегает спекулируя небольшие слова , основанные на правилах из New York Times Руководство по стилю, а также питания для нескольких частных случаев.
Некоторые из умений этих сценариев:
они пишут с заглавной буквы маленькие слова, такие как if, in, of, on и т. д., но не используют их, если они ошибочно написаны с заглавной буквы.
сценарии предполагают, что слова с заглавными буквами, кроме первого символа, уже правильно написаны с заглавной буквы. Это означает, что они оставят слово вроде «iTunes» в покое, а не превратят его в «ITunes» или, что еще хуже, «Itunes».
они пропускают любые слова с точками; «Example.com» и «del.icio.us» останутся строчными.
у них есть жестко запрограммированные хаки, специально предназначенные для работы со странными случаями, например «AT&T» и «Q&A», оба из которых содержат маленькие слова (at и a), которые обычно должны быть строчными.
Первое и последнее слово заголовка всегда пишутся с заглавной буквы, поэтому ввод, такой как «Нечего бояться», будет преобразован в «Нечего бояться».
Маленькое слово после двоеточия будет заглавным.
Вы можете скачать его здесь .
capitalize (word)
Это должно сработать. Я понимаю иначе.
>>> mytext = u'i am a foobar bazbar'
>>> mytext.capitalize()
u'I am a foobar bazbar'
>>>
Хорошо, как сказано в ответе выше, вы должны сделать настраиваемый регистр:
mytext = u'i am foobar bazbar '
def xcaptilize(word):
skipList = ['a', 'an', 'the', 'am']
if word not in skipList:
return word.capitalize()
return word
k = mytext.split(" ")
l = map(xcaptilize, k)
print " ".join(l)
Это выводит
I am a Foobar Bazbar
В методе заголовка Python 2.7 есть недостаток.
value.title()
вернет Carpenter ' S Assistant, если значение равно Carpenter' s Assistant
Лучшее решение, вероятно, от @BioGeek с использованием titlecase от Стюарта Колвилла. Это то же самое решение, которое предлагает @Etienne.
not_these = ['a','the', 'of']
thestring = 'the secret of a disappointed programmer'
print ' '.join(word
if word in not_these
else word.title()
for word in thestring.capitalize().split(' '))
"""Output:
The Secret of a Disappointed Programmer
"""
Название начинается с заглавной буквы, что не соответствует статье.
Однострочный с использованием понимания списка и тернарного оператора
reslt = " ".join([word.title() if word not in "the a on in of an" else word for word in "Wow, a python one liner for titles".split(" ")])
print(reslt)
Сломать:
for word in "Wow, a python one liner for titles".split(" ")
Разбивает строку на список и запускает цикл for (в понимании списка)
word.title() if word not in "the a on in of an" else word
использует собственный метод title()
для заголовка строки, если это не статья
" ".join
объединяет элементы списка с разделителем (пробел)
Один важный случай, который не рассматривается, - это аббревиатуры (решение python-titlecase может обрабатывать акронимы, если вы явно указываете их как исключения). Вместо этого я предпочитаю просто избегать погружения в корпус. При таком подходе аббревиатуры, уже написанные в верхнем регистре, остаются в верхнем регистре. Следующий код является модификацией кода, изначально предоставленного dheerosaur.
# This is an attempt to provide an alternative to ''.title() that works with
# acronyms.
# There are several tricky cases to worry about in typical order of importance:
# 0. Upper case first letter of each word that is not an 'minor' word.
# 1. Always upper case first word.
# 2. Do not down case acronyms
# 3. Quotes
# 4. Hyphenated words: drive-in
# 5. Titles within titles: 2001 A Space Odyssey
# 6. Maintain leading spacing
# 7. Maintain given spacing: This is a test. This is only a test.
# The following code addresses 0-3 & 7. It was felt that addressing the others
# would add considerable complexity.
def titlecase(
s,
exceptions = (
'and', 'or', 'nor', 'but', 'a', 'an', 'and', 'the', 'as', 'at', 'by',
'for', 'in', 'of', 'on', 'per', 'to'
)
):
words = s.strip().split(' ')
# split on single space to maintain word spacing
# remove leading and trailing spaces -- needed for first word casing
def upper(s):
if s:
if s[0] in '‘“"‛‟' + "'":
return s[0] + upper(s[1:])
return s[0].upper() + s[1:]
return ''
# always capitalize the first word
first = upper(words[0])
return ' '.join([first] + [
word if word.lower() in exceptions else upper(word)
for word in words[1:]
])
cases = '''
CDC warns about "aggressive" rats as coronavirus shuts down restaurants
L.A. County opens churches, stores, pools, drive-in theaters
UConn senior accused of killing two men was looking for young woman
Giant asteroid that killed the dinosaurs slammed into Earth at ‘deadliest possible angle,’ study reveals
Maintain given spacing: This is a test. This is only a test.
'''.strip().splitlines()
for case in cases:
print(titlecase(case))
При запуске выдает следующее:
CDC Warns About "Aggressive" Rats as Coronavirus Shuts Down Restaurants L.A. County Opens Churches, Stores, Pools, Drive-in Theaters
UConn Senior Accused of Killing Two Men Was Looking for Young Woman
Giant Asteroid That Killed the Dinosaurs Slammed Into Earth at ‘Deadliest Possible Angle,’ Study Reveals
Maintain Given Spacing: This Is a Test. This Is Only a Test.
re
нужно? Есть"".split
функция, которая делает то же самое.