2016-10-03 65 views
0

如何使pythonic?re.search()如果結果是無

def money_from_string(s): 
    gold = re.search("([0-9]+)g", s) 
    silver = re.search("([0-9]+)s", s) 
    copper = re.search("([0-9]+)c", s) 
    s = re.sub("[0-9]+g", "", s) 
    s = re.sub("[0-9]+s", "", s) 
    s = re.sub("[0-9]+c", "", s) 
    assert (len(s.strip()) == 0) # should be 0 

    return (gold.group() or 0) * 10000 + (silver.group() or 0) * 100 + (copper.group() or 0) 

這不起作用,因爲如果goldNonegold.group()將拋出一個錯誤。

輸入例子&預期成果:

s = "15g17s5c" -> 150000 + 1700 + 5 -> 151705 
s = "15g5s" -> 150000 + 500  -> 150500 
s = "15g"  -> 150000   -> 150000 
s = "17s5c" -> 1700 + 5   -> 1705 
s = "5c"  -> 5     -> 5 

請注意,我在輸入相應的檢查,以確保它實際上是正確的格式。 IE瀏覽器。它匹配:

MONEY_PATTERNS = [ 
    "([0-9]+g[ ]*[0-9]+s[ ]*[0-9]+c)", # g/s/c 
    "([0-9]+g[ ]*[0-9]+s)", # g/s 
    "([0-9]+g[ ]*[0-9]+c)", # g/c 
    "([0-9]+s[ ]*[0-9]+c)", # s/c 
    "([0-9]+g)", # g 
    "([0-9]+s)", # s 
    "([0-9]+c)", # c 
] 
+1

你想比檢查它是否'None'並返回不同的東西以外的東西? – khelwood

+4

's'看起來像什麼?我可以從你的代碼猜測,但我不應該 – brianpck

+6

我擔心它pythonic之前是正確的。 –

回答

-1

如果返回值是None,你可以簡單地檢查,並沒有與0更換。這似乎適合你正在嘗試做的事情。

def money_from_string(s): 
    gold = re.search("([0-9]+)g", s) 
    silver = re.search("([0-9]+)s", s) 
    copper = re.search("([0-9]+)c", s) 
    if str(gold) in 'None': 
     gold = 0 
    if str(silver) in 'None': 
     silver = 0 
    if str(copper) in 'None': 
     copper = 0 
    s = re.sub("[0-9]+g", "", s) 
    s = re.sub("[0-9]+s", "", s) 
    s = re.sub("[0-9]+c", "", s) 
    assert (len(s.strip()) == 0) # should be 0 

    return ((gold.group() * 10000 + silver.group() * 100 + copper.group()) 
+0

編輯:你已經做了。謝謝。 – searchengine27

+0

是的,並且返回消息沒有用,因爲它不會幫助'gold.group()'。謝謝。 –

+0

如果'None'中的str(gold)不起作用,'None'將被視爲一個數組。當gold.group()存在並且不能乘以10000時,gold.group()將返回一個字母'g'的字符串 – rtaft

1

這裏是我將如何實現你的程序。

注:

  • 必須使用int()將字符串轉換爲整數
  • 我會分開計算驗證,但在這兩種情況下使用相同的正則表達式。
  • 我會用字典而不是代碼來保存金屬的值。
  • 通過使用金屬字符類,我只需要撥打re.findall()一次。
  • 我的正則表達式允許更豐富的庫存字符串集,例如"10g 10g 10g"代表30個金件。

 

import re 

money_from_string_pattern = re.compile(r"(\d+)([gsc])") 


def is_money_from_string_valid(s): 
    return not money_from_string_pattern.sub("", s).strip() 


def money_from_string(s): 
    value = {'g': 10000, 's': 100, 'c': 1} 
    inventory = money_from_string_pattern.findall(s) 
    return sum(int(amount) * value[metal] for amount, metal in inventory) 

assert money_from_string("11g 22s 33c") == 112233 
assert money_from_string("11g") == 110000 
assert money_from_string("11g 11g") == 220000 

assert is_money_from_string_valid("11g 22s 33c") == True 
assert is_money_from_string_valid("11g") == True 
assert is_money_from_string_valid("11g 11g") == True 

assert is_money_from_string_valid("11 g 22s 33c") == False 
assert is_money_from_string_valid("11g 22q") == False 
assert is_money_from_string_valid("stackoverflow.com") == False