我正在尝试使用Python中的正则表达式从字符串中提取数据。
该字符串是您的第一个订单" 15%折扣"。我想从这个字符串中提取15。为此,我正在做 -
import re
pattern = r'.*(\d+)\s*\%.*off.*'
string = '15% Off your first order'
m = re.match(pattern, string, re.I)
print m.group(1)
但是,这会返回5
而不是15
。我错过了什么?
答案 0 :(得分:3)
实际问题在这里
.*(\d+)
.*
贪婪。所以实际匹配就是这样的。
r'.*(\d+)\s*\%.*off.*'
.*
首先匹配整个字符串,因为它是贪婪的并检查RegEx是否满足。由于它不满意,它会留下最后一个字符并检查它是否与RegEx匹配。因此,它会持续执行此操作并匹配1
,并发现(\d+)\s*\%.*off.*
与字符串的其余部分匹配。因此,.*
实际上匹配到1
并离开\d+
以匹配5.这就是它给出5
的原因。像这样把它变成非贪婪的
r'.*?(\d+)\s*\%.*off.*'
现在,.*
由于?
而非贪婪。因此,它将尽可能地匹配。因此,它在此处不匹配,因为\d+
匹配15。
注意:如您所见,它必须迭代尝试所有可能的匹配。所以这是非常低效的。你可以像这样写
r'.*?(\d+)\s*?\%\s*?off.*'
由于我们在任何地方使用非贪婪的运算符,它将比原始的贪婪版本更好。
答案 1 :(得分:1)
从您的模式中移除.*
并使用search
代替match
让比赛从任何地方开始:
pattern = r'(\d+)\s*\%.*off.*'
m = re.search(pattern, string, re.I)
答案 2 :(得分:0)
你可以这个正则表达式匹配:
^\d+(?=% Off)
确保该数字从字符串开始,并且数字为% Off