我的格式为“2010年10月28日”(或simillar)。现在我想将月份的全名更改为更短版本(在本例中为Oct)。为此,我准备了一本字典:
_mapping = {'January': 'Jan',
'February': 'Feb',
'March': 'Mar',
'April': 'Apr',
'May': 'May',
'June': 'Jun',
'July': 'Jul',
'August': 'Aug',
'September': 'Sep',
'October': 'Oct',
'November': 'Nov',
'December': 'Dec'}
并且在替换的方法中,我写了以下内容:
def fetch(self, pno):
...
date = #get data (working fine)
for l, s in self._mapping.iteritems():
pubdate = date.replace(l, s)
print l + " -> " + pubdate #this is only for debug
(pubd_month, self.pubd_day, self.pubd_year) = pubdate.split(' ')
print pubd_month, self.pubd_day, self.pubd_year
print pubdate
执行结果是:
February -> October 28, 2008
October -> Oct 28, 2008
January -> October 28, 2008
April -> October 28, 2008
November -> October 28, 2008
March -> October 28, 2008
August -> October 28, 2008
May -> October 28, 2008
December -> October 28, 2008
June -> October 28, 2008
September -> October 28, 2008
July -> October 28, 2008
October
October 28, 2008
正如你所看到的那样,当它找到十月但是在循环之外时,替换就没问题了,我又得到了满月的名字。我做错了什么?
另一个问题是:有更短的方法吗?
答案 0 :(得分:3)
由于您始终使用pubdate
上的替换替换date
,因此您将覆盖任何成功匹配。
如果月份在替换之前的字符串中,则首先测试,或者将pubdate
替换为pubdate.replace()
结果:
pubdate = #get data (working fine)
for l, s in self._mapping.iteritems():
pubdate = pubdate.replace(l, s)
或者,使用测试:
date = #get data (working fine)
for l, s in self._mapping.iteritems():
if l in date:
pubdate = date.replace(l, s)
如果找到超过一个月的名称,后者仍会导致pubdate
被覆盖。或者,如果只有一个月匹配,请使用break
提前结束循环:
date = #get data (working fine)
for l, s in self._mapping.iteritems():
if l in date:
pubdate = date.replace(l, s)
break
警告:如果找不到没有匹配,则永远不会分配pubdate
,您将获得UnboundLocal
例外。
答案 1 :(得分:3)
不需要_mapping
。如果您使用datetime.datetime个对象,strftime
方法可以为您返回缩写的月份:
import datetime as DT
def short_date(date):
date = DT.datetime.strptime(date, '%B %d, %Y')
return date.strftime('%b %d, %Y')
print(short_date('October 28, 2010'))
打印
Oct 28, 2010
如果您的日期字符串有多种格式,那么您可以使用dateutil的parser.parse方法,而不是使用strptime(date, '%B %d, %Y')
解析它们。为了获得最大的灵活性,您可能最好尽早将日期字符串解析为datetime.datetime
个对象,并尽可能使用strftime
格式化它们。