2017-09-02 52 views
0

我正在尋找識別在python前面可能有或沒有一個隨機字符的月份。例如,我想確定:在前面識別帶有隨機字符的月份

  1. loctober截至10
  2. yaug爲八月

字母前面並不總是L或Y,並且在多隻8月份個月前和十月。

我試圖鑑定這些個月這樣的:

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 
+0

'[a-z] jan'是一個不是正則表達式的字符串,使用're.compile'使它成爲正則表達式。 –

+0

'in'運算符使用平等('==')而不是're.match'。雖然我會推薦類似於@ DanilSperansky的方法。你不需要正則表達式。 – SwiftsNamesake

+0

我假設它沒關係*主要信件是什麼? – SwiftsNamesake

回答

2

我想借此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 
+0

+1集似乎在Python中被糟糕的使用不足(據我所知)。它可以在一定程度上提高性能,並可能教導OP新的東西。 – SwiftsNamesake

0

'loct' in odd_months檢查odd_months是否包括'loct'與否。數組中沒有這樣的字符串,所以它返回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 
+0

很好的答案。一套可能會稍微快一點,也許你應該''.lowercase()''s''。但它並不能解釋爲什麼OP的代碼不起作用。 – SwiftsNamesake

+0

@SwiftsNamesake謝謝你的提示,我添加了一個關於OP的代碼的通知,並且更改了我的代碼 –

+1

Downvoter,請你自己解釋一下。 –

0

「[AZ]揚」是一個字符串不是一個正則表達式,使用字符串,而不是像這樣:

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

def is_oddmonth(month): 
    return any(odm in month.lower() for odm in odd_months) 

print(is_oddmonth('lOct')) # True 
print(is_oddmonth('yaUg')) # True 
print(is_oddmonth('januArysd')) # True 
print(is_oddmonth('yammay')) # True 
print(is_oddmonth('decimal')) # True 
print(is_oddmonth('novel')) # True 

print(is_oddmonth('ocr')) # False 
print(is_oddmonth('auf')) # False 
print(is_oddmonth('jaduary')) # False 
print(is_oddmonth('mat')) # False 
print(is_oddmonth('nod')) # False 
print(is_oddmonth('dek')) # False 
0

您可以使用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個字母的表示形式是唯一的。爲此,你可以使用一個dict同時與3個字母和全名和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 
+0

謝謝。很高興你注意到,操作系統實際上是在尋找一個轉換,而不是一個布爾(儘管代碼沒有反映這一點)。最後,你可以使用endswith而不是in,儘管它們都有點寬容。但是,也許該操作不關心。 – SwiftsNamesake