47 votes

Python title() avec des apostrophes

Y a-t-il un moyen d'utiliser .title() pour obtenir la sortie correcte d'un titre avec des apostrophes ? Par exemple :

"john's school".title() --> "John'S School"

Comment puis-je obtenir le titre correct ici, "John's School" ?

77voto

Frédéric Hamidi Points 123646

Si vos titres ne contiennent pas plusieurs caractères d'espacement à la suite (ce qui serait un effondrement), vous pouvez utiliser string.capwords() à la place :

>>> import string
>>> string.capwords("john's school")
"John's School"

EDITAR: Comme Chris Morgan l'indique à juste titre ci-dessous, vous pouvez résoudre le problème de l'écrasement des espaces en spécifiant " " dans le sep argument :

>>> string.capwords("john's    school", " ")
"John's    School"

7 votes

Et c'est exactement équivalent à ' '.join(x.capitalize() for x in s.split()) .

4 votes

Et si vous tenez à ne pas réduire les espaces multiples, vous pouvez spécifier l'option sep argument : string.capwords("john's school", ' ') .

0 votes

@Chris, très bon point, je vais modifier ma réponse en conséquence. Merci :)

17voto

Art Taylor Points 779

Cela est difficile dans le cas général, car certaines apostrophes simples sont légitimement suivies d'un caractère majuscule, comme les noms irlandais commençant par "O'". string.capwords() fonctionnera dans de nombreux cas, mais ignorera tout ce qui est entre guillemets. string.capwords("le principal de Jean dit, 'non'") ne renverra pas le résultat que vous attendez peut-être.

>>> capwords("John's School")
"John's School"
>>> capwords("john's principal says,'no'")
"John's Principal Says,'no'"
>>> capwords("John O'brien's School")
"John O'brien's School"

Un problème plus ennuyeux est que le titre lui-même ne produit pas les bons résultats. Par exemple, dans l'anglais d'usage américain, les articles et les prépositions ne prennent généralement pas la majuscule dans les titres ou les gros titres. (Chicago Manual of Style).

>>> capwords("John clears school of spiders")
'John Clears School Of Spiders'
>>> "John clears school of spiders".title()
'John Clears School Of Spiders'

Vous pouvez installer facilement le module de titrage qui vous sera beaucoup plus utile, et qui fait ce que vous aimez, sans les problèmes de capwords. Il y a encore beaucoup de cas limites, bien sûr, mais vous irez beaucoup plus loin sans trop vous soucier d'une version écrite personnellement.

>>> titlecase("John clears school of spiders")
'John Clears School of Spiders'

5voto

Yugal Jindle Points 5931

Je pense que ça peut être délicat avec title()

Essayons quelque chose de différent :

def titlize(s):
    b = []
    for temp in s.split(' '): b.append(temp.capitalize())
    return ' '.join(b)

titlize("john's school")

// You get : John's School

J'espère que cela vous aidera ! !

2 votes

Vous n'avez pas besoin d'une bibliothèque supplémentaire ici !

6 votes

Félicitations, vous venez de réimplémenter string.capwords() (qui se trouve dans la bibliothèque standard de Python, entre autres :)

0 votes

Cela vaut la peine si c'est le cas d'utilisation.

2voto

user2962794 Points 127

Bien que les autres réponses soient utiles et plus concises, elles peuvent vous poser quelques problèmes. Par exemple, s'il y a de nouvelles lignes ou tabulations dans votre chaîne. De même, les mots comportant un trait d'union (qu'il s'agisse d'un trait d'union régulier ou non) peuvent poser problème dans certains cas, de même que les mots commençant par une apostrophe. Toutefois, en utilisant des expressions régulières (en utilisant une fonction pour l'argument de remplacement de l'expression régulière), vous pouvez résoudre ces problèmes :

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's 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))

Quoi qu'il en soit, vous pouvez modifier ce document pour compenser tout autre problème, tel que les backticks et autres, si nécessaire.

Si vous êtes d'avis que la casse des titres doit conserver les prépositions, les conjonctions et les articles en minuscules, sauf s'ils se trouvent au début ou à la fin du titre, vous pouvez essayer un code tel que celui-ci (mais il y a quelques mots ambigus que vous devrez déterminer par le contexte, tels que 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)

0voto

user698585 Points 3019

Si vous devez tenir compte des tirets, utilisez :

import string
" ".join(
    string.capwords(word, sep="-")
    for word in string.capwords(
        "john's school at bel-red"
    ).split()
)
# "John's School At Bel-Red"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X