使用正则表达式从Python字符串中提取数字

5

我想从字符串中提取并打印出变量号码“-34.99”:

myString = "Test1 [cm]:     -35.00/-34.99/-34.00/0.09"

字符串中的值将会改变。如何使用Python中的正则表达式来实现?

提前感谢。


你总是想要在以 / 分隔的列表中的第二个数字吗? - João Silva
2
如果字符串总是这样的话,正则表达式就有点杀鸡焉用牛刀了:myString.split()[-1].split("/")[1] - DSM
DSM,在我的代码中,myString 是大量行。我使用正则表达式和 re.compile 来查找其他字符串。感谢您有用的答案。 - dmaster
2个回答

14

非正则表达式的解决方案是:

myString = "Test1 [cm]:     -35.00/-34.99/-34.00/0.09"  
print myString.split("/")[1]

点击这里测试此代码。


其中一种正则表达式解决方案如下:

import re 
myString = "Test1 [cm]:     -35.00/-34.99/-34.00/0.09" 
print re.search(r'(?<=\/)[+-]?\d+(?:\.\d+)?', myString).group()

这里测试以下这段代码。

解释:

(?<=\/)[+-]?\d+(?:\.\d+)?
└──┬──┘└─┬─┘└┬┘└───┬────┘
   │     │   │     │
   │     │   │     └ optional period with one or more trailing digits
   │     │   │
   │     │   └ one or more digits
   │     │
   │     └ optional + or -
   │
   └ leading slash before match 

太棒了!它起作用了!谢谢大家!Omega,你的回答是最好的! - dmaster
你可以考虑使用.split('/')[-3]。这样可以获取倒数第三个元素,避免描述中包含“/”字符的影响。 - jon
@Jon - 我认为斜杠是一个分隔符,因此在描述中不应该有这样的字符。 - Ωmega
2
放松点,我指出这一点是为了帮助提问者(或其他阅读此答案的人),以防他想将寻找的字段更改为第一个。 - user648852
实际上,我只需要提取平均数。统计格式:Test1 [cm]:[min/avg/max/mdev] - dmaster
显示剩余2条评论

1

对于这样的情况,re.findall非常适用:

>>> import re
>>> myString = "Test1 [cm]:     -35.00/-34.99/-34.00/0.09"
>>> re.findall(r'([+-]?\d+\.\d+)',myString)
['-35.00', '-34.99', '-34.00', '0.09']

你可以使用列表推导式直接获取浮点数:

>>> [float(f) for f in re.findall(r'([+-]?\d+\.\d+)',myString)]
[-35.0, -34.99, -34.0, 0.09]

或者第二个像这样:

>>> re.findall(r'([+-]?\d+\.\d+)',myString)[1]
'-34.99'

问题在于您会接受多大范围的文本浮点数?一些没有小数点的?指数?

>>> myString = "Test1 [cm]:     -35.00/-34.99/-34.00/0.09/5/1.0e6/1e-6"  

哎呀!使用正则表达式变得更加困难了。

实际上,你最好只使用Python的字符串操作:

>>> ''.join([s for s in myString.split() if '/' in s]).split('/')
['-35.00', '-34.99', '-34.00', '0.09', '5', '1.0e6', '1e-6']

您可以通过相同的方式获取第n个。
>>> n=2
>>> ''.join([s for s in myString.split() if '/' in s]).split('/')[n]
'-34.00'

然后所有奇怪的情况都可以在没有更难的正则表达式的情况下工作:

>>> map(float,''.join([s for s in myString.split() if '/' in s]).split('/'))
[-35.0, -34.99, -34.0, 0.09, 5.0, 1000000.0, 1e-06]

我有点担心单位的问题:如果"[cm]"变成了"[cm/s]",那么前几个术语就会很奇怪。 - DSM
@DSM:是的,我想你可以验证分割的片段是否包含数字或使用try/catch语句块。由于所选的正则表达式仅适用于第一个字段之后的匹配,因此OP似乎只关心第二个匹配。 - user648852
1
这就是为什么我选择了 myString.split()[-1].split("/")[1],尽管它在其他情况下也会失败。也许可以使用 map(float, myString[myString.find(':')+1:].split("/"))?只有一个例子可供参考,很难知道应该有多普遍,或者我们可以依赖哪些不变量。不过,我确实喜欢使用分隔符的想法,而不是编写复杂的正则表达式来处理所有情况。 - DSM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接