【问题标题】:Pythonic way to parse a number out of a string that has a postfix从具有后缀的字符串中解析数字的 Pythonic 方法
【发布时间】:2016-12-22 19:49:24
【问题描述】:

使用 Python 3。

我有一个字符串,例如128kb/s5mb/s,或者像42! 这样简单的字符串。数字字符和它的后缀之间没有空格,所以我不能直接调用int(text)

我只想将128542 的值捕获为一个整数。

目前,我刚刚编写了一个辅助函数,它将所有数字累积成一个字符串并在第一个非数字字符处中断。

def read_int_from_string(text):
    s = ""
    val = 0
    for c in text:
        if (c >= '0') and (c <= '9'):
            s += c
        else:
            break
    if s:
        val = int(s)
    return val

上面的工作正常,但是有没有更pythonic的方法来做到这一点

【问题讨论】:

    标签: python python-3.x string-parsing


    【解决方案1】:

    这是正则表达式看起来合理的场景之一:

     import re
    
     leadingdigits = re.compile(r'^\d+')
    
     def read_int_from_string(text):
         return int(leadingdigits.match(text).group(0))
    

    如果您讨厌正则表达式,您可以这样做以将原始循环的逻辑基本推送到 C 层,尽管它可能会更慢:

     from itertools import takewhile
    
     def read_int_from_string(text):
         return int(''.join(takewhile(str.isdigit, text)))
    

    【讨论】:

      【解决方案2】:

      你可以用str.isdigit,这个怎么样?

      >> int(filter(str.isdigit, '128kb/s'))
         128
      

      对于 Python 3。因为 filter 在 Python 3 中返回可迭代

      int(''.join(filter(str.isdigit, '128kb/s')))
      

      【讨论】:

      • 这种方法的缺陷是当数字停止时它会继续运行,而不是中断;如果字符串后面有数字,它们都会被默默地组合在一起(所以"128 foo/10bar"被解析为12810,原始代码将得到128)。您可以使用 itertools.takewhile(在所有 Python 版本上都包含在 ''.join 中,在 Python 3 上也需要使用 filter)而不是 filter 来修复它,但它仍然会有点慢。
      • 旁注:无论如何,如果您只是要去''.join,请不要将filter 包装在Py3 上的list 中; ''.join 将采用任意可迭代对象,因此 list 包装是无意义的忙碌工作。
      • @ShadowRanger 是的,您将filter 包装在list 中是对的。如果您不想将所有数字连接在一起,您可以随时使用int(list(filter(str.isdigit, '128kb/100s))[0]),它返回128
      • 嗯...不。int(list(filter(str.isdigit, '128kb/100s))[0]) 返回1,因为谓词是逐个字符应用的,它不会对给定类型的运行进行分组。 list 将只是 ['1', '2', '8', '1', '0', '0'] 没有上下文信息来确定第一次数字运行的结束位置。 itertools.groupby 可以为您提供必要的上下文信息,但这是一个相当重量级的解决方案,因为itertools.takewhile 涵盖了所需的行为,所以它是不必要的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-20
      • 2014-01-23
      • 1970-01-01
      • 1970-01-01
      • 2020-07-06
      • 1970-01-01
      • 2011-08-22
      相关资源
      最近更新 更多