Python中的正则表达式无法正确匹配

时间:2015-01-20 07:14:44

标签: python regex

我正在尝试使用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。我错过了什么?

3 个答案:

答案 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