如何在Python中将字符串转换为标题格式?

160

示例:

HILO -> Hilo
new york -> New York
SAN FRANCISCO -> San Francisco

有没有库或标准方法来执行这个任务?


19
这不是“驼峰式命名法”,而是“首字母大写”,你需要哪个? - Andrew Marshall
14
驼峰式命名法长这样。 - Jonathan M
6
你的例子使用帕斯卡命名法。 - David Betz
我使用了这个答案,效果非常好。https://stackoverflow.com/a/74912560/17598016 - Procodedev
10个回答

343

为什么不使用title?文档中已经有了说明:

>>> "they're bill's friends from the UK".title()
"They'Re Bill'S Friends From The Uk"

如果你真的想要 PascalCase,可以使用这个:

>>> ''.join(x for x in 'make IT pascal CaSe'.title() if not x.isspace())
'MakeItPascalCase'

7
我认为"They're"中的'r'应该小写。而"Bill's"中的's'一定要小写。 - Daniel Fischer
3
注意:在 title 的文档中已经提到了这个问题:“该算法使用的是语言无关的单词定义,即连续字母组成的单词。这个定义在许多情况下都有效,但这意味着缩写和所有格中的撇号会形成单词边界,这可能不是期望的结果。” 可能的解决方案之一是使用 Laurence 回答中的正则表达式 r"['\w]+",这样撇号就不会结束匹配(必要时可以添加其他标点符号)。 - Andrew Clark
26
记录一下,最后一个CamelCase示例的更好方法是 'make IT camel CaSe'.title().replace(' ', '') - Henry Gomersall
23
如果有其他人觉得自己像是吃了错药一样——这是帕斯卡命名法,而不是驼峰命名法。 - serverpunk
6
代码不错,但驼峰式命名不应该以大写字母开头。试试这个:def toCamel(s): ret = ''.join(x for x in s.title() if not x.isspace()) return ret[0].lower() + ret[1:] 用法: toCamel("WRITE this in camelcase") 'writeThisInCamelcase' - Ron Kalian
1
我刚刚遇到了 title()。深奥。 - Evhz

34

这个会始终小写,并剥离非字母数字字符:

def camelCase(st):
    output = ''.join(x for x in st.title() if x.isalnum())
    return output[0].lower() + output[1:]

15
def capitalizeWords(s):
  return re.sub(r'\w+', lambda m:m.group(0).capitalize(), s)

re.sub可以接受一个函数作为“replacement”(而不仅仅是字符串,这是大多数人熟悉的用法)。这个 repl 函数将会对每个匹配到的模式调用一个 re.Match 对象,并且返回值(应该是一个字符串)将被用作替换该匹配项的结果。

同样的内容,稍微详细一些:

WORD_RE = re.compile(r'\w+')

def capitalizeMatch(m):
  return m.group(0).capitalize()

def capitalizeWords(s):
  return WORD_RE.sub(capitalizeMatch, s)

这将预编译模式(通常被认为是良好的形式),并使用命名函数代替lambda表达式。


这个很棒,我正在努力理解lambda函数,谢谢你的帮助。 - daydreamer
1
@JohnMachin 我只是问了一下,因为我认为添加一些解释会使你的答案更完整、更好。 - N.N.
@Laurence Gonsalves 这里的 lambda 函数是做什么用的? - Zion
这里的lambda函数是做什么的?根据我的理解和你的解释,我明白了这个意思。当你在re.sub中使用一个函数时,每个“match”都会被传递给该函数?而且由于正则表达式中的“matches”有分组,所以才有了这一行代码“lambda m:m.group(0).capitalize()”? - Zion
@Zion 是的。当 re.sub 给定一个可调用对象(例如:函数)作为“替换”时,它将匹配对象传递给该可调用对象,并期望得到一个字符串,这实际上是它用作替换的内容。如果您觉得 lambda 表达式令人困惑,那么“更长版本”以更冗长的方式完全执行相同的操作。 - Laurence Gonsalves

8
潜在的库:https://pypi.org/project/stringcase/ 示例:
import stringcase
stringcase.camelcase('foo_bar_baz') # => "fooBarBaz"

虽然有疑问它是否会保留空格。(示例显示它会删除空格,但是有一个错误跟踪器问题指出它会保留空格。)


1
当然。一直在寻找一个软件包。这个软件包也有snakecase和其他转换函数。 - s2t2

6

只需使用 .title(),它将把每个单词的第一个字母转换为大写,其余为小写:

>>> a='mohs shahid ss'
>>> a.title()
'Mohs Shahid Ss'
>>> a='TRUE'
>>> b=a.title()
>>> b
'True'
>>> eval(b)
True

6

注意:为什么我要提供另一个答案?这个回答基于问题的标题和"camelcase"的定义,即:一系列单词被连接在一起(没有空格!),使得每个原始单词的首字母大写(其余小写),除了系列中的第一个单词(它完全是小写)。同时假设"所有字符串"都指ASCII字符集; Unicode将无法使用此解决方案。

简单

根据上述定义,这个函数

import re
word_regex_pattern = re.compile("[^A-Za-z]+")

def camel(chars):
  words = word_regex_pattern.split(chars)
  return "".join(w.lower() if i is 0 else w.title() for i, w in enumerate(words))

当调用时,会以这种方式产生结果

camel("San Francisco")  # sanFrancisco
camel("SAN-FRANCISCO")  # sanFrancisco
camel("san_francisco")  # sanFrancisco

更复杂的

请注意,当输入一个已经采用驼峰命名法的字符串时,它将失败!

camel("sanFrancisco")   # sanfrancisco  <-- noted limitation

更不简单了

请注意,它无法处理许多Unicode字符串。

camel("México City")    # mXicoCity     <-- can't handle unicode

对于这些情况(或其他可能通过一些创意引入的情况),我没有解决方案。所以,就像所有与字符串有关的事情一样,要考虑自己的边缘情况,并祝你在Unicode方面好运!


你如何在不知道句子含义的情况下确定一个字符串是驼峰式命名?在你的“不那么简单”的例子中,“sanfRancisco”和“itSnotcaMelcAse”都是驼峰式命名。 - Patrice Bernassola
我猜你的输入中有撇号或其他标点符号?我应该记录其他失败的输入。绝对是一个好发现。你提供的输入是什么? - Marc
1
我的意思是,没有空格的字符序列必须被视为一个单词。如果不知道句子的含义,就不能从中提取单词。将“sanfRancisco”或“itSnotcaMelcAse”作为camel()的输入,您会发现输出结果是相同的。 - Patrice Bernassola
哦,我明白了 - 是的,我认为你是对的。我过度拟合了解决方案。我会更新它。 - Marc

6
为什么不自己写一个呢?像这样的东西可能会满足您的要求:
def FixCase(st):
    return ' '.join(''.join([w[0].upper(), w[1:].lower()]) for w in st.split())

谢谢,那帮了我很大的忙。我的错,我一开始没想到要写一个。 - daydreamer

2
def camelCase(st):
    s = st.title()
    d = "".join(s.split())
    d = d.replace(d[0],d[0].lower())
    return d

0

来自 Code Wars - 用 Python 编写简单的 .camelCase 方法,将字符串中的每个单词首字母大写且无空格。 camelcase("hello case") => HelloCase camelcase("camel case word") => CamelCaseWord

def camel_case(string):
    titled_string = string.title()
    space_joined_string = titled_string.replace(' ', '')
    return space_joined_string

0
我想在这篇文章中做出我的小贡献:
def to_camelcase(str):
  return ' '.join([t.title() for t in str.split()])

实际上,str.title()是相同的,而且您可以节省计算成本。 - JuanB

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