带有撇号的Python标题()

时间:2011-11-20 06:50:41

标签: python string uppercase

有没有办法使用.title()从带有撇号的标题中获取正确的输出?例如:

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

我如何在此处获得正确的标题"John's School"

5 个答案:

答案 0 :(得分:63)

如果您的标题连续不包含多个空格字符(可以折叠),则可以改为使用string.capwords()

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

编辑:正如Chris Morgan在下面正确地说的那样,您可以通过在" "参数中指定sep来缓解空白崩溃问题:

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

答案 1 :(得分:11)

在一般情况下这很困难,因为有些单个撇号合法地后跟一个大写字符,例如以“O”开头的爱尔兰名字。 string.capwords()在很多情况下会起作用,但会忽略引号中的任何内容。 string.capwords(“约翰的校长说,'不'”)不会返回你可能期望的结果。

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

一个更令人讨厌的问题是标题本身并没有产生正确的结果。例如,在美国使用英语中,文章和介词通常不会在标题或标题中大写。 (芝加哥风格手册)。

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

您可以轻松安装对您更有用的titlecase module,并按照您的问题做您喜欢的事情。当然,仍有许多边缘情况,但你会更进一步,而不必过多担心个人写的版本。

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

答案 2 :(得分:5)

我认为使用title()

可能会非常棘手

让我们尝试不同的东西:

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

希望有所帮助.. !!

答案 3 :(得分:2)

虽然其他答案有用且更简洁,但您可能会遇到一些问题。例如,如果字符串中有新行或制表符。此外,带符号的单词(无论是常规的还是非断开的连字符)在某些情况下可能是一个问题,以及以撇号开头的单词。但是,使用正则表达式(使用正则表达式替换参数的函数)可以解决这些问题:

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

无论如何,你可以编辑它来补偿任何进一步的问题,例如反对和你有什么需要。

如果您认为标题框应该保留,例如介词,连词和文章小写,除非它们位于标题的开头或结尾,您可以试试这样的代码(但那里你需要通过上下文来解决一些含糊不清的词,例如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)

答案 4 :(得分:0)

恕我直言,最佳答案是@Frédéric's one。但是,如果您已将字符串分隔为单词,并且知道如何实现string.capwords,则可以避免不必要的连接步骤:

def capwords(s, sep=None):
    return (sep or ' ').join(
        x.capitalize() for x in s.split(sep)
    )

因此,您可以这样做:

# here my_words == ['word1', 'word2', ...]
s = ' '.join(word.capitalize() for word in my_words)