Python:使用string.format()将单词首字母大写

26

使用字符串格式化是否可以将单词大写?例如,

"{user} did such and such.".format(user="foobar")

应该返回 "Foobar did such and such."

请注意,我非常清楚 .capitalize() 的作用;然而,这是我正在使用的代码的(非常简化版本):


请注意,我非常清楚 .capitalize() 的作用;然而,这是我正在使用的代码的(非常简化版本):
printme = random.choice(["On {date}, {user} did la-dee-dah. ",
                         "{user} did la-dee-dah on {date}. "
                         ])

output = printme.format(user=x,date=y)

正如你所见,仅在.format()中将user定义为x.capitalize()是不起作用的,因为它也会被(错误地)应用于第一种情况。而且由于我无法预测命运,没有办法预先知道哪个random.choice会被选中。我该怎么办?

附注:仅仅对每个字符串分别进行格式化处理并使用.capitalize()(即对需要它的那些字符串)并不可行,因为printme实际上是从40多个字符串中进行选择的。


你为什么会随意更改用户名的大小写? - Ignacio Vazquez-Abrams
@IgnacioVazquez-Abrams用户名实际上等于用户名或者代词--对于代词,不总是要大写它们。 - tehsockz
等等...你会改变用户名的大小写,但不会改代词吗?为什么这样做?人们希望他们的用户名与他们在框中输入的大小写完全一致。 - user2357112
@user2357112 不在这个项目中:p 不,说真的,我正在处理一个数据集,我可以确定每个用户名已经被大写了(这是软件所要求的,而我没有编写该软件)。 - tehsockz
4个回答

18
如@IgnacioVazquez-Abrams所说,创建string.Formatter的子类,可以扩展/更改格式字符串处理。
在您的情况下,您需要重载方法convert_field
from string import Formatter
class ExtendedFormatter(Formatter):
    """An extended format string formatter

    Formatter with extended conversion symbol
    """
    def convert_field(self, value, conversion):
        """ Extend conversion symbol
        Following additional symbol has been added
        * l: convert to string and low case
        * u: convert to string and up case

        default are:
        * s: convert with str()
        * r: convert with repr()
        * a: convert with ascii()
        """

        if conversion == "u":
            return str(value).upper()
        elif conversion == "l":
            return str(value).lower()
        # Do the default conversion or raise error if no matching conversion found
        return super(ExtendedFormatter, self).convert_field(value, conversion)

# Test this code

myformatter = ExtendedFormatter()

template_str = "normal:{test}, upcase:{test!u}, lowcase:{test!l}"


output = myformatter.format(template_str, test="DiDaDoDu")
print(output)

2
我认为你的例子有错误。在convert_field的最后一行中,你应该返回调用super的输出,而不是return value,即:return super(ExtendedFormatter, self)... - peter.slizik
@peter.slizik 确实。 - sherpya

12
您可以传递额外的值并不使用它们,就像这个轻量级选项一样。

您可以传递额外的值并不使用它们,就像这个轻量级选项一样

printme = random.choice(["On {date}, {user} did la-dee-dah. ",
                         "{User} did la-dee-dah on {date}. "
                         ])

output = printme.format(user=x, date=y, User=x.capitalize())

最好的选择可能取决于您是否做得足够多,需要自己拥有完整的Formatter


2
我喜欢这种方法!是的,我正在更大规模地进行操作(超过600条消息,以及各种不同的功能——不仅仅是大小写转换),所以它并不完全适用于我的情况,但仍然值得记住。 - tehsockz

11
你可以创建自己的子类,继承string.Formatter,这样你就能够识别一个自定义的转换,并用它来改变字符串的大小写。
myformatter.format('{user!u} did la-dee-dah on {date}, and {pronoun!l} liked it. ',
                      user=x, date=y, pronoun=z)

2
如果其他人有这个问题,可以参考一下需要更改的函数 - tehsockz
1
s/changed/overridden/ - Ignacio Vazquez-Abrams

5

只有在OP将f-string内联到random.choice中时,才能解决这个问题,但他可能有能力做到,也可能无法做到。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接