我试图从文本字符串say="每年12.5%的增长率"中提取百分比值,其中百分比可以是任何小于100的小数.当我try 的时候
re.sub(r'.*([0-9]{1,2}\.[0-9]).*',r'\1', text)
它的回报率是2.5.我认为,如果是{1,2}?
,这应该是结果.此外,{1,2}+
将返回"..multiple match.."错误.
虽然我已经使用了一些替代解决方案,但我很想知道我搞错了什么.
我试图从文本字符串say="每年12.5%的增长率"中提取百分比值,其中百分比可以是任何小于100的小数.当我try 的时候
re.sub(r'.*([0-9]{1,2}\.[0-9]).*',r'\1', text)
它的回报率是2.5.我认为,如果是{1,2}?
,这应该是结果.此外,{1,2}+
将返回"..multiple match.."错误.
虽然我已经使用了一些替代解决方案,但我很想知道我搞错了什么.
正如InSync comments 的那样,您的模式的问题是模式开头和结尾的.*是贪婪的,这意味着它匹配尽可能多的字符.
在您的示例文本字符串"Rate of Increase 12.5%in annum"中,模式开头的.*与整个字符串匹配,直到小数点前的最后一位(在本例中为1).然后,捕获组([0-9]{1,2}.[0-9])匹配剩余的数字(2.5),因为它满足小数点前有一位或两位,小数点后至少有一位的模式要求.最后,模式结尾处的.*与字符串的其余部分匹配("Per Anyum").
要纠正这一点,可以通过添加?在.*之后:
re.sub(r'.*?([0-9]{1,2}\.[0-9]).*', r'\1', text)
此修改使.*?匹配尽可能少的字符,确保捕获组([0-9]{1,2}.[0-9])仅捕获所需的十进制数.
通过此更改,校正后的模式将提取预期结果,即12.5
注意:如果百分比值可以是任何小于100的小数,您可以考虑修改正则表达式模式,以允许小数点前的数字大于9.您可以使用{1,2}匹配一个或两个数字,也可以使用后跟(?<;!\d)的{1,2}匹配一个或两个数字,前提是它们前面没有另一个数字.在这种情况下,您必须这样做:
result = re.sub(r'.*?(?<!\d)([0-9]+\.[0-9]).*', r'\1', text)
这种修改后的模式通过使用负回溯断言(?<;!\d)来判断匹配的十进制数之前没有数字,从而确保小数不是较大数的一部分.
希望能对你有所帮助!