我试图从文本字符串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)来判断匹配的十进制数之前没有数字,从而确保小数不是较大数的一部分.

希望能对你有所帮助!

Python相关问答推荐

为什么我的主页不会重定向到详细视图(Django)

Python中的锁定类和线程以实现dict移动

基本链合同的地址是如何计算的?

如何使用上下文管理器创建类的实例?

在Pandas框架中截短至固定数量的列

Pandas 第二小值有条件

有症状地 destruct 了Python中的regex?

Python中绕y轴曲线的旋转

对所有子图应用相同的轴格式

如何在Python脚本中附加一个Google tab(已经打开)

如何使用表达式将字符串解压缩到Polars DataFrame中的多个列中?

Godot:需要碰撞的对象的AdditionerBody2D或Area2D以及queue_free?

有没有一种ONE—LINER的方法给一个框架的每一行一个由整数和字符串组成的唯一id?

为什么if2/if3会提供两种不同的输出?

如何找出Pandas 图中的连续空值(NaN)?

在matplotlib中使用不同大小的标记顶部添加批注

Pandas—堆栈多索引头,但不包括第一列

如何在Gekko中使用分层条件约束

BeautifulSoup:超过24个字符(从a到z)的迭代失败:降低了首次深入了解数据集的复杂性:

mdates定位器在图表中显示不存在的时间间隔