2010-09-16 9 views
62

¿Existe una forma estándar en Python de escribir una cadena (es decir, las palabras comienzan con mayúsculas, todos los caracteres restantes tienen minúscula) pero dejando artículos como and, in y of en minúscula?Título de una cadena con excepciones

Respuesta

116

Hay algunos problemas con esto. Si usa dividir y unir, se ignorarán algunos caracteres de espacio en blanco. Los métodos de capitalizar y título incorporados no ignoran el espacio en blanco.

>>> 'There  is a way'.title() 
'There  Is A Way' 

Si una oración comienza con un artículo, no desea la primera palabra de un título en minúsculas.

Teniendo esto en cuenta:

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 
+5

+1 para el caso "oración que comienza con un artículo" – yassin

+0

¿Por qué es necesario 're'? Hay una función '" ".split' que hace lo mismo. – wizzwizz4

+0

@ wizzwizz4: 'str.split' no considera espacios contiguos. 're.split' retiene espacios. Entonces, esta función no consume ningún espacio. – dheerosaur

14

hay estos 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 

No hay opción artículo minúsculas. Tendría que codificarlo usted mismo, probablemente mediante el uso de una lista de artículos que desea reducir.

+0

titlecase.py artículos en minúsculas. –

3
capitalize (word) 

Esto debería hacer. Lo entiendo de manera diferente.

>>> mytext = u'i am a foobar bazbar' 
>>> mytext.capitalize() 
u'I am a foobar bazbar' 
>>> 

Ok como se ha dicho en la respuesta anterior, usted tiene que hacer una costumbre capitalizar:

mitexto = u'i soy un bazbar foobar'

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) 

Esto da salida a

I am a Foobar Bazbar 
+0

Eso no es lo que quiero. Quiero obtener "Soy un Foobar Bazbar" – yassin

+0

@Yassin Ezbakhe: Editado mi respuesta, esto debería funcionar para usted. La lista de artículos puede levantarse fácilmente desde cualquier diccionario – pyfunc

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

El título comienza con la tapa palabra italizada y que no coincide con el artículo.

40

Utilice el módulo titlecase.py! Funciona solo para ingles

>>> from titlecase import titlecase 
>>> titlecase('i am a foobar bazbar') 
'I Am a Foobar Bazbar' 
+1

El módulo de título no funciona si la cadena que está convirtiendo contiene un número en algún lugar. – Troy

+1

@Troy parece que el problema con el número es fijo, o no lo hice. Ejemplo: titlecase ('one 4 two') -> 'One 4 Two'. Ahora título ('1one') -> '1one', pero '1one'.title() ->' 1One '. aunque este último caso es un caso marginal y no estoy seguro de que "1One" sea la titulación correcta. Tampoco me preocupa lo suficiente como para tomar mi libro de gramática. –

+0

No funcionará en el caso de "321 A BROADWAY STREET" donde consigo "321 a Broadway Street". El uso de la solución propuesta por dheerosaur arriba produce "321 A Broadway Street". – MoreScratch

9

Stuart Colville has made a Python port de a Perl script written by John Gruber para convertir cadenas en caso de título, pero no ofrece la capitalización de las pequeñas palabras basado en reglas del manual del New York Times del estilo, así como la restauración de varios casos especiales .

Algunos de la inteligencia de estos scripts:

  • que capitaliza pequeñas palabras como si, a, de, en, etc., pero se no-provecho si están en mayúsculas en forma errónea la entrada.

  • los scripts suponen que las palabras con letras mayúsculas que no sean el primer carácter ya están en mayúscula correctamente. Esto significa que dejarán una palabra como "iTunes" solo, en lugar de convertirla en "ITunes" o, lo que es peor, "Itunes".

  • omiten las palabras con puntos de línea; "Example.com" y "del.icio.us" permanecerán en minúscula.

  • tienen hacks no modificables específicamente para tratar los casos impares, como “AT & T” y “Q & A”, ambos de los cuales contienen pequeñas palabras (a y a) que normalmente debería ser minúscula.

  • La primera y la última palabra del título están siempre en mayúscula, por lo que los comentarios como "Nada de qué temer" se convertirán en "Nada de qué temer".

  • Una palabra pequeña después de dos puntos se escribirá en mayúscula.

Puede descargarlo here.

3

El método del título de Python 2.7 tiene un defecto.

value.title() 

volverá Carpenter S Asistente cuando el valor es carpintero 's Asistente

La mejor solución es probablemente el de @BioGeek usando TitleCase de Stuart Colville. Que es la misma solución propuesta por @Etienne.

0

de una sola línea utilizando la lista de comprensión y el operador 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) 

Desglose:

for word in "Wow, a python one liner for titles".split(" ") divide la cadena en una lista y se inicia un bucle (en la lista comprehenstion)

word.title() if word not in "the a on in of an" else word usa el método nativo title() para poner título a la cadena si no es un artículo

" ".join se une a los elementos de la lista con un separador de (espacio)

Cuestiones relacionadas