从维基百科

时间:2016-11-22 23:55:27

标签: python regex string parsing

我正在尝试使用Python来调用API并清理一堆代表电影预算的字符串。

到目前为止,我有以下6种数据变体。

  1. “120万美元”
  2. “$ 1433333”
  3. “200万美元”
  4. “US $ 1,644,736(est。)
  5. “6-7百万美元”
  6. “300万英镑”
  7. 到目前为止,我只使用下面的代码解析了1和2而没有问题。处理所有其他案件或下面可能未列出的一般案例的最佳方法是什么?

    def clean_budget_string(input_string):
    number_to_integer = {'million' : 1000000, 'thousand' : 1000}
    budget_parts = input_string.split(' ')
    #Currently, only indices 0 and 1 are necessary for computation
    
    text_part = budget_parts[1]
    
    if text_part in number_to_integer:
        number = budget_parts[0].lstrip('$')
        int_representation = number_to_integer[text_part]
        return int(float(number) * int_representation)
    else:
        number = budget_parts[0]
        idx_dollar = 0
        for idx in xrange(len(number)):
            if number[idx] == '$':
                idx_dollar = idx
    
        return int(number[idx_dollar+1:].replace(',', ''))
    

2 个答案:

答案 0 :(得分:1)

我接近这样的解析任务的方式 - 我很高兴听到其他意见 - 将你的功能分解成几个部分,每个部分识别输入字符串中的单个信息

例如,我首先要确定可以从字符串中解析哪个浮点数,忽略货币和数量级(一百万,一千)现在:

f = float(''.join([c for c in input_str if c in '0123456789.']))

(您可能希望在最终得到一个尾随点时添加错误处理,因为像'est。'这样的附加内容。)

然后,在第二步中,确定是否需要将浮点数相乘以调整正确的数量级。一种方法是使用多个if语句:

if 'million' in input_str :
  oom = 6
elif 'thousand' in input_str :
  oom = 3
else :
  oom = 1

# adjust number for order of magnitude
f = f*math.pow(10, oom)

这些检查当然可以通过使用正则表达式来解决格式上的细微差别。

最后,您再次使用一个或多个if语句分别确定输入字符串中提到的货币:

if '£' in input_str :
  currency = 'GBP'
else :
  currency = 'USD'

现在,尚未处理的一个案例是破折号,其中给出了较低和较高的估计值。使函数与这些输入一起工作的一种方法是将初始输入字符串拆分为破折号,并使用第一个(或第二个)子字符串作为初始浮点解析的输入。所以我们用这样的代码替换我们的第一行代码:

if '-' in input_str :
  lower = input_str.split('-')[0]
  f = float(''.join([c for c in lower if c in '0123456789.']))
else :
  f = float(''.join([c for c in input_str if c in '0123456789.']))

答案 1 :(得分:0)

使用正则表达式和字符串替换方法,如果需要,我还添加了固化的返回。 相应地修改以处理更多输入或乘数,如亿等。

import re
# take in string and return integer amount and currency
def clean_budget_string(s):
    mult_dict = {'million':1000000,'thousand':1000}
    tmp = re.search('(^\D*?)\s*((?:\d+\.?,?)+)(?:-\d+)?\s*((?:million|thousand)?)', s).groups()
    currency = tmp[0]
    mult = tmp[-1]
    tmp_int = ''.join(tmp[1:-1]).replace(',', '') # join digits and multiplier, remove comma
    tmp_int = int(float(tmp_int) * mult_dict.get(mult, 1))
    return tmp_int, currency


>>? clean_budget_string("$1.2 million")
(1200000, '$')
>>? clean_budget_string("$1,433,333")
(1433333, '$')
>>? clean_budget_string("US$ 2 million")
(2000000, 'US$')
>>? clean_budget_string("US$1,644,736 (est.)")
(1644736, 'US$')
>>? clean_budget_string("$6-7 million")
(6000000, '$')
>>? clean_budget_string("£3 million")
(3000000, '£') # my script don't recognize the £ char, might need to set the encoding properly