【问题标题】:Find all floats or ints in a given string查找给定字符串中的所有浮点数或整数
【发布时间】:2017-07-09 22:50:08
【问题描述】:

给定一个字符串"Hello4.2this.is random 24 text42",我想返回所有整数或浮点数[4.2, 24, 42]。所有其他问题都有只返回 24 的解决方案。即使数字旁边有非数字字符,我也想返回一个浮点数。由于我是 Python 新手,我试图避免使用正则表达式或其他复杂的导入。我不知道如何开始。请帮忙。以下是一些研究尝试:Python: Extract numbers from a string,这不起作用,因为它不识别 4.2 和 42。还有其他类似提到的问题,可悲的是没有一个识别 4.242

【问题讨论】:

  • 如果没有 re,你就不会做好这件事。使用正则表达式:它们存在于这个任务中。
  • @AlexanderHuszagh:“如果没有 re,你就不会做好这件事。”嗯,这听起来像是一个挑战……
  • @WarrenWeckesser,他们的关键词是 well。这绝对是可行的,但如果没有 re,它就不会高效、可读或可能没有性能。
  • 浏览了 re 模块后,我才意识到创建 re 是为了做这些事情。这只是让我意识到我在掌握基本 Python 的道路上还有多长时间。

标签: python arrays


【解决方案1】:

来自perldoc perlretut的正则表达式:

import re
re_float = re.compile("""(?x)
   ^
      [+-]?\ *      # first, match an optional sign *and space*
      (             # then match integers or f.p. mantissas:
          \d+       # start out with a ...
          (
              \.\d* # mantissa of the form a.b or a.
          )?        # ? takes care of integers of the form a
         |\.\d+     # mantissa of the form .b
      )
      ([eE][+-]?\d+)?  # finally, optionally match an exponent
   $""")
m = re_float.match("4.5")
print m.group(0)
# -> 4.5

从字符串中获取所有数字:

str = "4.5 foo 123 abc .123"
print re.findall(r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?", str)
# -> ['4.5', ' 123', ' .123']

【讨论】:

  • 这比我的好几个联赛。 +1
  • +1 我不知道正则表达式,但我可以直观地理解为什么这是有道理的。另外,您在第二个 sn-p 上使用三重字符串是否有特定原因?
【解决方案2】:

使用正则表达式可能会为您提供解决此问题的最简洁的代码。简洁性是难以超越的

re.findall(r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?", str)

来自 pythad 的回答。

但是,您说“我试图避免使用正则表达式”,所以这里有一个不使用正则表达式的解决方案。它显然比使用正则表达式的解决方案要长一点(而且可能要慢得多),但并不复杂。

代码逐个字符地循环输入。 当它从字符串中提取每个字符时,它会将其附加到current(一个包含当前正在解析的数字的字符串)if 附加它仍然保持有效数字。当遇到无法附加到current 的字符时,current 会保存到数字列表中,但前提是current 本身不是'''.''-' 或@ 之一987654329@;这些是可能以数字开头但本身不是有效数字的字符串。

保存current 时,将删除结尾的'e''e-''e+'。这将发生在诸如'1.23eA' 之类的字符串中。在解析该字符串时,current 最终会变为'1.23e',但随后遇到了'A',这意味着该字符串不包含有效的指数部分,因此'e' 被丢弃。

保存current后,会被重置。通常current被重置为'',但是当触发current被保存的字符是'.''-'时,current被设置为那个字符,因为这些字符可能是一个新号码。

这是函数extract_numbers(s)return numbers 之前的行将字符串列表转换为整数和浮点值列表。如果您只想要字符串,请删除该行。

def extract_numbers(s):
    """
    Extract numbers from a string.

    Examples
    --------
    >>> extract_numbers("Hello4.2this.is random 24 text42")
    [4.2, 24, 42]

    >>> extract_numbers("2.3+45-99")
    [2.3, 45, -99]

    >>> extract_numbers("Avogadro's number, 6.022e23, is greater than 1 million.")
    [6.022e+23, 1]
    """
    numbers = []
    current = ''
    for c in s.lower() + '!':
        if (c.isdigit() or
            (c == 'e' and ('e' not in current) and (current not in ['', '.', '-', '-.'])) or
            (c == '.' and ('e' not in current) and ('.' not in current)) or
            (c == '+' and current.endswith('e')) or
            (c == '-' and ((current == '') or current.endswith('e')))):
            current += c
        else:
            if current not in ['', '.', '-', '-.']:
                if current.endswith('e'):
                    current = current[:-1]
                elif current.endswith('e-') or current.endswith('e+'):
                    current = current[:-2]
                numbers.append(current)
            if c == '.' or c == '-':
                current = c
            else:
                current = ''

    # Convert from strings to actual python numbers.
    numbers = [float(t) if ('.' in t or 'e' in t) else int(t) for t in numbers]

    return numbers

【讨论】:

  • +1 谢谢!你的代码很棒。我主要要求一个没有正则表达式的解决方案,这样我就可以理解真正编码背后的逻辑——因为据我所知 JS 和 C 没有正则表达式。
【解决方案3】:

如果您想从字符串中获取整数或浮点数,请按照pythad 的操作 方式...

如果您想从单个字符串中获取整数和浮点数,请执行以下操作:

string = "These are floats: 10.5, 2.8, 0.5; and these are integers: 2, 1000, 1975, 308 !! :D"

for line in string:
    for actualValue in line.split():
        value = []

            if "." in actualValue:
                value = re.findall('\d+\.\d+', actualValue)
            else:
                value = re.findall('\d+', actualValue)
                
            numbers += value

【讨论】:

    猜你喜欢
    • 2020-06-27
    • 2021-06-11
    • 1970-01-01
    • 2022-10-16
    • 2013-10-06
    • 1970-01-01
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多