【问题标题】:How to extract a part of a string如何提取字符串的一部分
【发布时间】:2017-09-18 16:58:39
【问题描述】:

我有这个字符串:

-1007.88670550662*p**(-1.0) + 67293.8347365694*p**(-0.416543501823503)

但实际上我有很多这样的字符串:

a*p**(-1.0) + b*p**(c)

其中 a,b 和 c 是双倍的。我想提取这个字符串的 a、b 和 c。如何使用 Python 做到这一点?

【问题讨论】:

  • 使用正则表达式并在解析时提取双精度。
  • 谢谢,但我不知道正则表达式...我该如何使用它?
  • @GuyDavis 见docs
  • @GuyDavis 听起来是学习正则表达式的好机会。
  • Here 是一些非常清晰的指导,带有示例,包括数字!

标签: python string python-2.7 python-3.x split


【解决方案1】:
import re
s = '-1007.88670550662*p**(-1.0) + 67293.8347365694*p**(-0.416543501823503)'
pattern = r'-?\d+\.\d*'  

a,_,b,c = re.findall(pattern,s)
print(a, b, c)

输出

('-1007.88670550662', '67293.8347365694', '-0.416543501823503')

s 是你的测试字符串,什么不是,pattern 是正则表达式模式,我们正在寻找浮点数,一旦我们使用findall() 找到它们,我们将它们分配回abc

请注意,此方法仅适用于您的字符串格式与您提供的格式相同的情况。否则你可以使用模式来匹配你想要的。

像大多数人在 cmets 中所说的那样编辑,如果你需要在你的正数前面包含一个+,你可以使用这个模式r'[-+]?\d+\.\d*'

【讨论】:

  • 您可能希望pattern = r'-?\d+\.\d+' 捕捉可能的减号。
  • 和一个可能的加号
  • 这不匹配-1.0吗?
  • @PedroLobito 确实如此,我不理会它,就像我的回答状态一样,如果字符串以 a*p**(-1.0) + b*p**(c) 中的确切格式给出,就像 op 所述,那么它没有问题
  • @PedroLobito:-1.0 被分配给_,按惯例用作一次性变量。
【解决方案2】:

使用正则表达式

(-?\d+\.?\d*)\*p\*\*\(-1\.0\)\s*\+\s*(-?\d+\.?\d*)\*p\*\*\((-?\d+\.?\d*)\)

我们可以的

import re

pat = r'(-?\d+\.?\d*)\*p\*\*\(-1\.0\)\s*\+\s*(-?\d+\.?\d*)\*p\*\*\((-?\d+\.?\d*)\)'

regex = re.compile(pat)

print(regex.findall('-1007.88670550662*p**(-1.0) + 67293.8347365694*p**(-0.416543501823503)'))

将打印[('-1007.88670550662', '67293.8347365694', '-0.416543501823503')]

【讨论】:

  • 无意冒犯,但这可能会阻止一些人学习正则表达式。
【解决方案3】:

如果您的格式是一致的,并且您不想深入研究正则表达式(请查看regex101,顺便说一句),您可以分道扬镳。

这是一个开始:

>>> s= "-1007.88670550662*p**(-1.0) + 67293.8347365694*p**(-0.416543501823503)"
>>> a, buf, c = s.split("*p**")
>>> b = buf.split()[-1]
>>> a,b,c
('-1007.88670550662', '67293.8347365694', '(-0.416543501823503)')
>>> [float(x.strip("()")) for x in (a,b,c)]
[-1007.88670550662, 67293.8347365694, -0.416543501823503]

【讨论】:

  • 这对于没有正则表达式的解决方案来说是个好主意。可以这样简化s.replace('*p**(-1.0) +', '*p**').split('*p**')
【解决方案4】:

你可以使用类似的东西:

import re
a,_,b,c = re.findall(r"[\d\-.]+", subject)
print(a,b,c)

Demo

【讨论】:

    【解决方案5】:

    虽然我更喜欢 MooingRawr 的答案,因为它很简单,但我会对其进行扩展以涵盖更多情况。

    浮点数可以转换为具有多种格式的字符串:

    • 指数格式(例如2.0e+07
    • 没有前导数字(例如.5,等于0.5
    • 没有尾随数字(例如5.,等于5
    • 带加号的正数(例如+5,等于5
    • 没有小数部分的数字(整数)(例如05

    脚本

    import re
    
    test_values = [
        '-1007.88670550662*p**(-1.0) + 67293.8347365694*p**(-0.416543501823503)',
        '-2.000e+07*p**(-1.0) + 1.23e+07*p**(-5e+07)',
        '+2.*p**(-1.0) + -1.*p**(5)',
        '0*p**(-1.0) + .123*p**(7.89)'
    ]
    
    pattern = r'([-+]?\.?\d+\.?\d*(?:[eE][-+]?\d+)?)'
    
    for value in test_values:
        print("Test with '%s':" % value)
        matches = re.findall(pattern, value)
        del matches[1]
        print(matches, end='\n\n')
    

    输出:

    Test with '-1007.88670550662*p**(-1.0) + 67293.8347365694*p**(-0.416543501823503)':
    ['-1007.88670550662', '67293.8347365694', '-0.416543501823503']
    
    Test with '-2.000e+07*p**(-1.0) + 1.23e+07*p**(-5e+07)':
    ['-2.000e+07', '1.23e+07', '-5e+07']
    
    Test with '+2.*p**(-1.0) + -1.*p**(5)':
    ['+2.', '-1.', '5']
    
    Test with '0*p**(-1.0) + .123*p**(7.89)':
    ['0', '.123', '7.89']
    

    【讨论】:

      【解决方案6】:

      re 模块当然可以为此工作,尽管正如其他答案中的一些 cmets 所指出的那样,极端情况可能很有趣——小数点、加号和减号等。它可能会更有趣;例如你的其中一个数字可以是虚构的吗?

      无论如何,如果您的字符串始终是有效的 Python 表达式,您可以使用 Python 的内置工具来处理它。 Here is a good generic explanation 关于 ast 模块的 NodeVisitor 类。将它用于您的示例非常简单:

      import ast
      
      x = "-1007.88670550662*p**(-1.0) + 67293.8347365694*p**(-0.416543501823503)"
      
      def getnums(s):
          result = []
          class GetNums(ast.NodeVisitor):
              def visit_Num(self, node):
                  result.append(node.n)
              def visit_UnaryOp(self, node):
                  if (isinstance(node.op, ast.USub) and
                      isinstance(node.operand, ast.Num)):
                      result.append(-node.operand.n)
                  else:
                      ast.NodeVisitor.generic_visit(self, node)
          GetNums().visit(ast.parse(s))
          return result
      
      print(getnums(x))
      

      这将返回一个包含表达式中所有数字的列表:

      [-1007.88670550662, -1.0, 67293.8347365694, -0.416543501823503]
      

      visit_UnaryOp 方法仅适用于 Python 3.x。

      【讨论】:

        猜你喜欢
        • 2020-12-18
        • 1970-01-01
        • 1970-01-01
        • 2023-04-08
        • 1970-01-01
        • 2012-04-01
        • 1970-01-01
        相关资源
        最近更新 更多