2016-10-03 136 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