【问题标题】:Extract scientific number from string从字符串中提取科学数字
【发布时间】:2013-08-09 17:43:25
【问题描述】:

我正在尝试从文本文件的行中提取科学数字。类似的东西

例子:

str = 'Name of value 1.111E-11   Next Name 444.4'

结果:

[1.111E-11, 444.4]

我已经在其他帖子中尝试过解决方案,但看起来这只适用于整数(也许)

>>> [int(s) for s in str.split() if s.isdigit()]
[]

float() 可以工作,但每次使用字符串时都会出错。

>>> float(str.split()[3])
1.111E-11
>>> float(str.split()[2])
ValueError: could not convert string to float: value

提前感谢您的帮助!!

【问题讨论】:

  • 将变量命名为str 是不明智的,因为它会覆盖内置变量。
  • 哦,是的,智慧之语。多少次我不得不对这样做的mo同事生气:P

标签: python string floating-point scientific-notation


【解决方案1】:

这可以通过正则表达式来完成:

import re
s = 'Name of value 1.111E-11   Next Name 444.4'
match_number = re.compile('-?\ *[0-9]+\.?[0-9]*(?:[Ee]\ *-?\ *[0-9]+)?')
final_list = [float(x) for x in re.findall(match_number, s)]
print final_list

输出:

[1.111e-11, 444.4]

请注意,我上面写的模式取决于小数点左侧至少存在一位数字。

编辑:

这是a tutorial and reference,我发现它对学习如何编写正则表达式模式很有帮助。

既然您要求解释正则表达式模式:

'-?\ *[0-9]+\.?[0-9]*(?:[Ee]\ *-?\ *[0-9]+)?'

一次一件:

-?        optionally matches a negative sign (zero or one negative signs)
\ *       matches any number of spaces (to allow for formatting variations like - 2.3 or -2.3)
[0-9]+    matches one or more digits
\.?       optionally matches a period (zero or one periods)
[0-9]*    matches any number of digits, including zero
(?: ... ) groups an expression, but without forming a "capturing group" (look it up)
[Ee]      matches either "e" or "E"
\ *       matches any number of spaces (to allow for formats like 2.3E5 or 2.3E 5)
-?        optionally matches a negative sign
\ *       matches any number of spaces
[0-9]+    matches one or more digits
?         makes the entire non-capturing group optional (to allow for the presence or absence of the exponent - 3000 or 3E3

注意:\d 是 [0-9] 的快捷方式,但我只是习惯使用 [0-9]。

【讨论】:

  • 很好的解释!!谢谢
  • 这个答案非常有用。但是我想补充一点,如果您将-? 修改为[-+]?,那么如果字符串将+ 用于正数或指数,它将正确匹配科学记数法。
【解决方案2】:

您总是可以只使用for 循环和try-except 语句。

>>> string = 'Name of value 1.111E-11   Next Name 444.4'
>>> final_list = []
>>> for elem in string.split():
        try:
            final_list.append(float(elem))
        except ValueError:
            pass


>>> final_list
[1.111e-11, 444.4]

【讨论】:

  • 不错。 +1 致力于鸭子打字。
  • 我更喜欢这种方法而不是正则表达式,但它假设数字周围有空格。如果数字周围有空格,则正则表达式是更好的解决方案。
  • @SethMMorton:我认为是这样,因为 OP 最初的方法是将数据拆分为空格,他比我更了解他的数据。 :)
  • @SukritKalra 我只是想向那些在未来找到这个答案但不一定有这个标准的人说清楚。
【解决方案3】:

我会使用正则表达式:

import re
s = 'Name of value 1.111E-11   Next Name 444.4'
print [float(x) for x in re.findall("-?\d+.?\d*(?:[Ee]-\d+)?", s)]

输出:

[1.111e-11, 444.4]

【讨论】:

  • 您需要在模式的开头使用-? 来捕获负数。
  • @Brionius - 不错的收获。谢谢。
  • 谢谢!这很好用。我已经阅读了关于 Regex 的 Python 文档,但我无法破译“-?\d+.?\d*(?:[Ee]-\d+)?”。你能简单解释一下吗?或者我在哪里可以找到?
  • @JoshMelson - 我在答案底部添加了对我使用的正则表达式模式的解释。它与 iCodez 的模式非常相似。
猜你喜欢
  • 1970-01-01
  • 2015-06-19
  • 2015-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-27
相关资源
最近更新 更多