Existe uma maneira padrão em Python para titlecase uma string (ou seja, palavras começar com caracteres maiúsculos, todos os caracteres restantes encaixotado têm minúsculas) mas os artigos que deixam como and
, in
eof
em minúsculas?
Respostas:
Existem alguns problemas com isso. Se você usar dividir e juntar, alguns caracteres de espaço em branco serão ignorados. Os métodos incorporados de capitalização e título não ignoram os espaços em branco.
>>> 'There is a way'.title()
'There Is A Way'
Se uma frase começa com um artigo, você não quer a primeira palavra de um título em minúsculas.
Tendo isto em mente:
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
não considera espaços contíguos. re.split
retém espaços. Portanto, esta função não ocupa nenhum espaço.
"".split()
não os considerasse, mas "".split(" ")
sim.
title_except('a whim of aN elephant', articles)
caso. Você pode usar a word.lower() in exceptions
condição de filtragem para corrigi-lo.
2001 a Space Odyssey
deve retornar 2001 A Space Odyssey
, onde a a
é maiúscula conforme segue um número. Desde já, obrigado.
Use o módulo titlecase.py ! Funciona apenas para inglês.
>>> from titlecase import titlecase
>>> titlecase('i am a foobar bazbar')
'I Am a Foobar Bazbar'
Existem estes métodos:
>>> mytext = u'i am a foobar bazbar'
>>> print mytext.capitalize()
I am a foobar bazbar
>>> print mytext.title()
I Am A Foobar Bazbar
Não há opção de artigo em minúsculas. Você mesmo teria que codificar isso, provavelmente usando uma lista de artigos que deseja reduzir.
Stuart Colville fez um port Python de um script Perl escrito por John Gruber para converter strings em maiúsculas, mas evita capitalizar palavras pequenas com base nas regras do Manual de estilo do New York Times, bem como atender a vários casos especiais.
Algumas das habilidades desses scripts:
eles capitalizam palavras pequenas como if, in, of, on , etc., mas irão retirá-las se estiverem erroneamente capitalizados na entrada.
os scripts pressupõem que as palavras com letras maiúsculas diferentes do primeiro caractere já estão corretamente capitalizadas. Isso significa que eles deixarão uma palavra como “iTunes” sozinha, em vez de transformá-la em “iTunes” ou, pior, “iTunes”.
eles pulam quaisquer palavras com pontos de linha; “Example.com” e “del.icio.us” permanecerão em letras minúsculas.
eles têm hacks codificados especificamente para lidar com casos ímpares, como “AT&T” e “Q&A”, ambos contendo palavras pequenas (at e a) que normalmente deveriam ser minúsculas.
A primeira e a última palavra do título são sempre maiúsculas, portanto, entradas como “Nada a ter medo” serão transformadas em “Nada a ter medo de”.
Uma pequena palavra após os dois pontos será maiúscula.
Você pode baixá-lo aqui .
capitalize (word)
Isso deve servir. Eu entendo de forma diferente.
>>> mytext = u'i am a foobar bazbar'
>>> mytext.capitalize()
u'I am a foobar bazbar'
>>>
Ok, como disse na resposta acima, você deve fazer uma capitalização personalizada:
meutexto = eu sou um 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)
Isso produz
I am a Foobar Bazbar
O método title do Python 2.7 tem uma falha.
value.title()
retornará Carpenter ' S Assistant quando o valor for Carpenter' s Assistant
A melhor solução é provavelmente a da @BioGeek usando titlecase de Stuart Colville. Qual é a mesma solução proposta por @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
"""
O título começa com palavra maiúscula e que não corresponde ao artigo.
Uma linha usando compreensão de lista e o operador ternário
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)
Demolir:
for word in "Wow, a python one liner for titles".split(" ")
Divide a string em uma lista e inicia um loop for (na compreensão da lista)
word.title() if word not in "the a on in of an" else word
usa o método nativo title()
para capitalizar a string se não for um artigo
" ".join
junta os elementos da lista com um separador de (espaço)
Um caso importante que não está sendo considerado são os acrônimos (a solução python-titlecase pode lidar com acrônimos se você os fornecer explicitamente como exceções). Em vez disso, prefiro simplesmente evitar o rebaixamento. Com essa abordagem, as siglas que já estão em maiúsculas permanecem em maiúsculas. O código a seguir é uma modificação daquele originalmente fornecido pelo 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))
Quando executado, ele produz o seguinte:
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
necessário? Existe uma"".split
função que faz o mesmo.