首页 > 解决方案 > Python regex - 贪婪的量词在所有情况下都不起作用

问题描述

对于这个问题,我试图在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)(.*)

它适用于除最后两个之外的所有上述测试字符串。沃斯起来了??

RegEx101 演示

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)

标签: pythonregexregex-greedy

解决方案


对于在 a 之前带有点的匹配数字,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

为此,它几乎是以前正则表达式的逆项,但不是使用积极的lookahead (?=),而是使用积极的lookbehind (?<=)。因此,当您使用时,(?<=x)您要确保所有内容都在x.

有了这个,你可以使用(?<=x)\s*?(\d*\.?\d+)和匹配 .sub() 你可以.*?(?<=x)\s*?(\d*\.?\d+).*

此处为 regex101 的链接。


推荐阅读