识别前面有随机字符的月份

Identify months with random characters in front

我想识别 python 中前面可能有也可能没有一个随机字符的月份。例如我想确定:

  1. 10 月作为 10 月
  2. yaug 作为 aug

前面的字母并不总是 l 或 y,而且前面的月份不止 august 和 october。

我试过像这样识别这些月份:

odd_months = ['[a-z]jan', '[a-z]january', '[a-z]feb', '[a-z]february', '[a-z]mar', '[a-z]march', 
          '[a-z]apr', '[a-z]april', '[a-z]may', '[a-z]jun', '[a-z]june', '[a-z]jul', 
          '[a-z]july', 'iaug',  '[a-z]august', '[a-z]sep', '[a-z]september', '[a-z]oct', 
          '[a-z]october', '[a-z]nov', '[a-z]november', '[a-z]dec', '[a-z]december']

例如

'loct' in odd_months #False 

'loct' in odd_months 检查 odd_months 是否包含 'loct'。数组中没有这样的字符串,所以returns False.

但无论如何我认为使用正则表达式是开销很大的。我会建议完全另一种方法:

def validate(s):
    months = {
        'jan', 'january', 'feb', 'february', 'mar', 'march', 'apr', 'april',
        'may', 'jun', 'june', 'jul', 'july', 'aug', 'august', 'sep', 'september',
        'oct', 'october', 'nov', 'november', 'dec', 'december'
    }

    if s in months:
        return s

    if s[1:] in months:
        return s[1:]

print(validate('apr')) #=> 'apr'
print(validate('qapr')) #=> 'apr'
print(validate('qqapr')) #=> None

您可以使用 dict 和正则表达式来执行以下操作:

odd_months={re.compile(r'\w?oct(?:ober)?'): "october", re.compile(r'\w?aug(?:ust)?'): "august"}

for s in ('loct', 'oct', 'loctober', 'yaug', 'waugust', 'nothingburger'):
    for pat, key in odd_months.items():
        if pat.match(s):
            print '"{}"=>{}'.format(s,key)
            break
    else:
        print '"{}" no match'.format(s) 

打印:

"loct"=>october
"oct"=>october
"loctober"=>october
"yaug"=>august
"waugust"=>august
"nothingburger" no match

您还可以利用每个月都是独一无二的,3 个字母的表示形式也是独一无二的。因此,您可以使用带有 3 个字母和全名的 dict 以及 in 运算符来测试一个月:

import calendar
def find_name(x):
   months={k.lower():v for k,v in 
            zip(calendar.month_name[1:]+calendar.month_abbr[1:], calendar.month_name[1:]*2)}    
   for k,v in months.items():
       if k in x.lower():
           return v
   else:
      return False  

我会利用 calendar 模块:

import calendar

names_and_abbrs = calendar.month_name[1:] + calendar.month_abbr[1:]

def isOddMonth(name):
    return (name.title() in names_and_abbrs) or (name[1:].title() in names_and_abbrs)

或者:

def isOddMonth(name):
    return any(n.title() in names_and_abbrs for n in (name, name[1:]))

示例使用:

isOddMonth('aug') == True
isOddMonth('loct') == True
isOddMonth('DECEMBER') == True
isOddMonth('februa') == False
isOddMonth('') == False
isOddMonth('123') == False