Python正则表达式-贪婪量词在所有情况下均不起作用

时间:2019-08-06 22:59:11

标签: python regex regex-greedy

关于这个问题,我试图隔离/返回x(乘法符号)之前的第一个int或float。

这是我的测试字符串:

2 x 3 kg PPG etc #returns 2
bob 2 x 3 kg PPG etc #returns 2
1.5x1.5kgPPGetcFred #returns 1.5
BobFred1.5x1.5kgPPGetcFred #returns 1.5
1.5 x 2.3 kg PPG Fred Bob #returns 5 (should return 1.5)
bob Fred 1.5 x 2.3 kg PPG Fred Bob #returns 5 (should return 1.5)

这是我的正则表达式:

.*?(\d+)(\.?)(\s*)(\d?)(x)(.*)

它适用于以上所有测试字符串 (最后两个除外)。 Vos iss up ??

RegEx101 Demo

Python代码示例:

import re

regex = r'.*?(\d+)(\.?)(\s*)(\d?)(x)(.*)'
regout = r'\1\2\4'
test_str = "1.5 x 2.3 kg PPG Fred Bob"

tmp = re.sub(regex, regout, test_str)
print(tmp)

2 个答案:

答案 0 :(得分:3)

要在x前用点号匹配数字,可以使用以下正则表达式:(\d*\.?\d+)\s*(?=x)

  • (\d*\.?\d+)创建一个由数字组成的组,这些数字位于点之间,例如:1、10、1.3、1.5、22.10等。
  • \s*匹配零到无限制的空格(数字和x之间可以有空格)
  • (?=x)确保x前的所有内容

如果您想使用.sub(),则必须匹配整个字符串,这可以使用.*?(\d*\.?\d+)\s*(?=x).*完成,就像您在注释中提到的那样。


编辑:OP在x之后要求匹配的数字。

为此,它几乎是前一个正则表达式的逆项,但是您没有使用正向后退(?=),而是使用了正向后退(?<=)。因此,当您使用(?<=x)时,要确保所有内容都在x之后。

与此匹配,可以使用(?<=x)\s*?(\d*\.?\d+),对于.sub(),可以使用.*?(?<=x)\s*?(\d*\.?\d+).*

regex101 here的链接。

答案 1 :(得分:1)

我的猜测是,您可能希望设计一个类似于以下内容的表达式:

(\d*(?:\.\d+)?)\s*x\s*(\d*(?:\.\d+)?)

假设.05是有效数字。

测试

import re

regex = r"(\d*(?:\.\d+)?)\s*x\s*(\d*(?:\.\d+)?)"
test_str = """
2 x 3 kg PPG etc
bob 2 x 3 kg PPG etc
1.5x1.5kgPPGetcFred
BobFred1.5x1.5kgPPGetcFred
1.5 x 2.3 kg PPG Fred Bob
bob Fred 1.5 x 2.3 kg PPG Fred Bob
bob Fred .005 x 2.3 kg PPG Fred Bob
"""

print(re.findall(regex, test_str))

输出

[('2', '3'), ('2', '3'), ('1.5', '1.5'), ('1.5', '1.5'), ('1.5', '2.3'), ('1.5', '2.3'), ('.005', '2.3')]

该表达式在regex101.com的右上角进行了解释,如果您想探索/简化/修改它,在this link中,您可以观察到它如何与某些示例输入匹配,如果愿意的话。