C'è un modo standard in Python per Titlecase una stringa (vale a dire le parole iniziano con caratteri maiuscoli, tutti i caratteri con carter rimanenti hanno minuscolo) ma che lasciano articoli come and
, in
e of
caratteri minuscoli?
Risposte:
Ci sono alcuni problemi con questo. Se utilizzi la divisione e l'unione, alcuni caratteri di spazio vuoto verranno ignorati. I metodi incorporati in maiuscolo e titolo non ignorano gli spazi vuoti.
>>> 'There is a way'.title()
'There Is A Way'
Se una frase inizia con un articolo, non vuoi che la prima parola di un titolo sia in minuscolo.
Tenendo a mente questi:
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
non considera gli spazi contigui. re.split
conserva gli spazi. Quindi, questa funzione non consuma spazi.
"".split()
non li considerasse ma lo ha "".split(" ")
fatto.
title_except('a whim of aN elephant', articles)
caso. È possibile utilizzare la word.lower() in exceptions
condizione di filtro per risolverlo.
2001 a Space Odyssey
dovrebbe restituire 2001 A Space Odyssey
, dove a
è in maiuscolo come segue un numero. Grazie in anticipo.
Usa il modulo titlecase.py ! Funziona solo per l'inglese.
>>> from titlecase import titlecase
>>> titlecase('i am a foobar bazbar')
'I Am a Foobar Bazbar'
Esistono questi metodi:
>>> mytext = u'i am a foobar bazbar'
>>> print mytext.capitalize()
I am a foobar bazbar
>>> print mytext.title()
I Am A Foobar Bazbar
Non esiste un'opzione articolo in minuscolo. Dovresti codificarlo tu stesso, probabilmente utilizzando un elenco di articoli che desideri ridurre.
Stuart Colville ha realizzato un port in Python di uno script Perl scritto da John Gruber per convertire le stringhe in maiuscole e minuscole, ma evita di usare le maiuscole in base alle regole del Manuale di stile del New York Times, oltre a soddisfare diversi casi speciali.
Alcune delle abilità di questi script:
mettono in maiuscolo le piccole parole come if, in, of, on , ecc., ma le rimuoveranno se sono erroneamente capitalizzate nell'input.
gli script presumono che le parole con lettere maiuscole diverse dal primo carattere siano già correttamente maiuscole. Ciò significa che lasceranno una parola come "iTunes" da sola, piuttosto che trasformarla in "ITunes" o, peggio, "Itunes".
saltano le parole con i punti di linea; "Example.com" e "del.icio.us" rimarranno in minuscolo.
hanno hack hard-coded specificatamente per trattare casi strani, come "AT&T" e "Q&A", che contengono entrambe piccole parole (at e a) che normalmente dovrebbero essere minuscole.
La prima e l'ultima parola del titolo sono sempre in maiuscolo, quindi input come "Niente di cui aver paura" verranno trasformati in "Niente di cui aver paura".
Una piccola parola dopo i due punti sarà in maiuscolo.
Puoi scaricarlo qui .
capitalize (word)
Questo dovrebbe bastare. Lo capisco diversamente.
>>> mytext = u'i am a foobar bazbar'
>>> mytext.capitalize()
u'I am a foobar bazbar'
>>>
Ok come detto nella risposta sopra, devi fare una maiuscola personalizzata:
mytext = u'io am a 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)
Questo produce
I am a Foobar Bazbar
Il metodo del titolo di Python 2.7 ha un difetto.
value.title()
restituirà Carpenter ' S Assistant quando il valore è Carpenter' 's Assistant
La soluzione migliore è probabilmente quella di @BioGeek usando titlecase di Stuart Colville. Che è la stessa soluzione proposta da @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
"""
Il titolo inizia con una parola in maiuscolo e non corrisponde all'articolo.
One-liner utilizzando la comprensione delle liste e l'operatore ternario
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)
Abbattersi:
for word in "Wow, a python one liner for titles".split(" ")
Divide la stringa in un elenco e avvia un ciclo for (nella comprensione della lista)
word.title() if word not in "the a on in of an" else word
utilizza il metodo nativo title()
per titolo la stringa se non è un articolo
" ".join
unisce gli elementi della lista con un separatore di (spazio)
Un caso importante che non viene considerato sono gli acronimi (la soluzione python-titlecase può gestire gli acronimi se li fornisci esplicitamente come eccezioni). Preferisco invece evitare semplicemente il down-case. Con questo approccio, gli acronimi che sono già maiuscoli rimangono in maiuscolo. Il codice seguente è una modifica di quello originariamente fornito da 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 viene eseguito, produce quanto segue:
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
necessario? C'è una"".split
funzione che fa lo stesso.