在python中替换字符串时的奇怪行为
我有一个日期,格式为“2010年10月28日”(或类似日期)。现在我想将月份的全名改为较短的版本(在本例中为十月)。为此,我准备了一本字典:在python中替换字符串时的奇怪行为,python,replace,Python,Replace,我有一个日期,格式为“2010年10月28日”(或类似日期)。现在我想将月份的全名改为较短的版本(在本例中为十月)。为此,我准备了一本字典: _mapping = {'January': 'Jan', 'February': 'Feb', 'March': 'Mar', 'April': 'Apr', 'May': 'May', 'June': 'Jun',
_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
正如你所看到的,当它找到10月份时,替换似乎还可以,但在循环之外,我又得到了一个完整的月份名称。我做错了什么
另一个问题:有没有较短的方法可以做到这一点?因为您总是在date
替换为publidate
,所以您会覆盖任何成功的匹配
在替换之前,如果月份在字符串中,则首先进行测试,或者将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
异常。因为您总是在date
上用替换项替换pubdate
,所以会覆盖任何成功的匹配项
在替换之前,如果月份在字符串中,则首先进行测试,或者将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
将永远不会被分配到,您将得到一个未绑定的本地
异常。不需要\u映射
。如果使用对象,则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的方法,而不是使用
strtime(date,'%B%d,%Y')对其进行解析。为了获得最大的灵活性,您最好尽早将日期字符串解析为datetime.datetime
对象,并使用strftime
尽可能晚地格式化它们。不需要\u映射。如果使用对象,则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的方法,而不是使用strtime(date,'%B%d,%Y')对其进行解析。为了获得最大的灵活性,您最好尽早将日期字符串解析为datetime.datetime
对象,并使用strftime
尽可能晚地格式化它们。嗯,我犯了一个愚蠢的错误。谢谢:)不过在这种特殊情况下,乌布托的解决方案更干净,所以我会把他标记为被接受。哈,我犯了个愚蠢的错误。谢谢:)不过在这种特殊情况下,乌布托的解决方案更干净,所以我会将其标记为已接受。请注意,%b
和%b
月份名称取决于区域设置。我发现,如果你的代码必须在不同的环境中运行,而你不能控制语言环境,那么你必须每月手动更换代码。那么有可能强制使用英语语言环境吗;老实说,替换字符串要容易得多。请参阅,以获取可在POSIX系统上工作的解决方案,前提是已生成区域设置。请注意,%b
和%b
月份名称取决于区域设置。我发现,如果你的代码必须在不同的环境中运行,而你不能控制语言环境,那么你必须每月手动更换代码。那么有可能强制使用英语语言环境吗;老实说,替换字符串要容易得多。如果已生成区域设置,请参阅,以获取可在POSIX系统上工作的解决方案。