Python中是否有一种标准的方法可以将字符串转换为标题格式(即每个单词以大写字母开头,所有其余的大小写字符均为小写),但保留像 "and"、"in" 和 "of" 这样的介词小写不变?
Python中是否有一种标准的方法可以将字符串转换为标题格式(即每个单词以大写字母开头,所有其余的大小写字符均为小写),但保留像 "and"、"in" 和 "of" 这样的介词小写不变?
>>> 'There is a way'.title()
'There Is A Way'
如果一句话以冠词开头,你不希望标题的第一个单词小写。
记住这些:
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
str.split
不会考虑连续的空格。re.split
会保留空格。因此,这个函数不会吞掉任何空格。 - dheerosaurtitle_except('a whim of aN elephant', articles)
这种情况无法正确工作。你可以使用 word.lower() in exceptions
过滤条件来修复它。 - Dariusz Walczaka
不是因为在字母后面而未大写,而是因为它是副标题的第一个单词。要识别副标题,需要看它是否在冒号 :
后面,所以实际上正确的标题应该是 2001: 太空漫游
。 - Joshua Coady:
- 我想在一个重命名文件的脚本中使用它。这就是为什么我会将 :
从名称中省略掉(或根据情况用 -
替换)。我认为电影标题通常比较灵活(在标题/命名规范上)。我将查看该文章,并查看我能够将哪些惯例带入代码中。 - ProGrammer使用 titlecase.py 模块!仅适用于英语。
>>> from titlecase import titlecase
>>> titlecase('i am a foobar bazbar')
'I Am a Foobar Bazbar'
有以下这些方法:
>>> mytext = u'i am a foobar bazbar'
>>> print mytext.capitalize()
I am a foobar bazbar
>>> print mytext.title()
I Am A Foobar Bazbar
没有小写文章选项。你需要自己编写代码,可能会使用一个你想要转换成小写的文章列表。
Stuart Colville 制作了一个 Python 版本的 由 John Gruber 编写的 Perl 脚本,用于将字符串转换为标题式大小写,但基于纽约时报风格指南中的规则避免对小词进行大写处理,同时还考虑了几种特殊情况。
这些脚本的一些巧妙之处:
他们将小单词(如if、in、of、on等)大写,但如果输入错误地大写了它们,则会将它们变成小写。
这些脚本假定除了第一个字符以外的大写字母已经正确大写。这意味着他们会保持像“iTunes”这样的单词不变,而不是把它搞成“ITunes”或者更糟糕的是“Itunes”。
他们跳过任何带有行点的单词;“example.com”和“del.icio.us”将保持小写。
他们有硬编码的特殊处理,以应对奇怪的情况,比如“AT&T”和“Q&A”,两者都包含小单词(at和a),这些单词通常应该是小写的。
标题的第一个和最后一个单词始终大写,因此像“Nothing to be afraid of”这样的输入将被转换为“Nothing to Be Afraid Of”。
冒号后面的小单词将被大写。
您可以在这里下载它。
capitalize (word)
>>> mytext = u'i am a foobar bazbar'
>>> mytext.capitalize()
u'I am a foobar bazbar'
>>>
好的,如上面的回复所说,您需要制作一个自定义的大写字母:
mytext = u'我是一个foobar bazbar'
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)
I am a Foobar Bazbar
Python 2.7的title方法存在一个缺陷。
value.title()
当值为 Carpenter's Assistant 时,将返回 Carpenter'S Assistant。
最佳解决方案可能是来自 @BioGeek 使用 Stuart Colville 的 titlecase。这也是 @Etienne 提出的相同解决方案。
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
"""
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)
说明:
for word in "Wow, a python one liner for titles".split(" ")
将字符串分割为列表,并在列表推导式中初始化一个for循环。
word.title() if word not in "the a on in of an" else word
如果不是冠词,则使用内置方法title()
将字符串变成标题格式。
" ".join
使用(空格)作为分隔符来连接列表元素。
一个重要的情况没有被考虑到,那就是缩写词(如果你明确地提供它们作为例外,python-titlecase 解决方案可以处理缩写词)。我更喜欢避免使用小写字母。采用这种方法,已经大写的缩写词将保持大写。以下代码是 dheerosaur 最初提供的修改版。
# This is an attempt to provide an alternative to ''.title() that works with
# acronyms.
# There are several tricky cases to worry about in typical order of importance:
# 0. Upper case first letter of each word that is not an 'minor' word.
# 1. Always upper case first word.
# 2. Do not down case acronyms
# 3. Quotes
# 4. Hyphenated words: drive-in
# 5. Titles within titles: 2001 A Space Odyssey
# 6. Maintain leading spacing
# 7. Maintain given spacing: This is a test. This is only a test.
# The following code addresses 0-3 & 7. It was felt that addressing the others
# would add considerable complexity.
def titlecase(
s,
exceptions = (
'and', 'or', 'nor', 'but', 'a', 'an', 'and', 'the', 'as', 'at', 'by',
'for', 'in', 'of', 'on', 'per', 'to'
)
):
words = s.strip().split(' ')
# split on single space to maintain word spacing
# remove leading and trailing spaces -- needed for first word casing
def upper(s):
if s:
if s[0] in '‘“"‛‟' + "'":
return s[0] + upper(s[1:])
return s[0].upper() + s[1:]
return ''
# always capitalize the first word
first = upper(words[0])
return ' '.join([first] + [
word if word.lower() in exceptions else upper(word)
for word in words[1:]
])
cases = '''
CDC warns about "aggressive" rats as coronavirus shuts down restaurants
L.A. County opens churches, stores, pools, drive-in theaters
UConn senior accused of killing two men was looking for young woman
Giant asteroid that killed the dinosaurs slammed into Earth at ‘deadliest possible angle,’ study reveals
Maintain given spacing: This is a test. This is only a test.
'''.strip().splitlines()
for case in cases:
print(titlecase(case))
运行时,它会产生以下结果:
CDC Warns About "Aggressive" Rats as Coronavirus Shuts Down Restaurants L.A. County Opens Churches, Stores, Pools, Drive-in Theaters
UConn Senior Accused of Killing Two Men Was Looking for Young Woman
Giant Asteroid That Killed the Dinosaurs Slammed Into Earth at ‘Deadliest Possible Angle,’ Study Reveals
Maintain Given Spacing: This Is a Test. This Is Only a Test.