首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将所有数值替换为格式化字符串

将所有数值替换为格式化字符串
EN

Stack Overflow用户
提问于 2016-08-24 10:28:56
回答 3查看 385关注 0票数 4

我想做的是:

查找字符串中的所有数值。

代码语言:javascript
复制
input_string = "高露潔光感白輕悅薄荷牙膏100   79.80"

numbers = re.finditer(r'[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?',input_string)

for number in numbers:
    print ("{}    start > {}, end > {}".format(number.group(), number.start(0), number.end(0)))

'''Output'''
>>100    start > 12, end > 15
>>79.80    start > 18, end > 23

然后,我想将所有整数和浮点值替换为某种格式:

INT_(number of digit)FLT(number of decimal places)

例如:100 -> INT_3 // 79.80 -> FLT_2

因此,expect输出字符串如下所示:

代码语言:javascript
复制
"高露潔光感白輕悅薄荷牙膏INT_3   FLT2"

但是Python中的字符串替换子字符串方法有点奇怪,它无法归档我想要做的事情。

因此,我尝试使用子字符串附加子字符串方法。

代码语言:javascript
复制
string[:number.start(0)] + "INT_%s"%len(number.group()) +.....

这看起来很愚蠢,最重要的是,我还是不能让它发挥作用。

有人能给我一些关于这个问题的建议吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-08-24 10:39:14

在可以对匹配执行各种操作的内部使用re.sub和回调方法:

代码语言:javascript
复制
import re
def repl(match):
    chunks = match.group(1).split(".")
    if len(chunks) == 2:
        return "FLT_{}".format(len(chunks[1]))
    else:
        return "INT_{}".format(len(chunks[0]))

input_string = "高露潔光感白輕悅薄荷牙膏100   79.80"
result = re.sub(r'[-+]?([0-9]*\.?[0-9]+)(?:[eE][-+]?[0-9]+)?',repl,input_string)
print(result)

Python演示

详细信息

  • regex现在在数字部分(([0-9]*\.?[0-9]+))上有一个捕获组,这将在repl方法中进行分析。
  • repl方法中,Group 1内容与.分割,以查看是否有浮点数/双值,如果有,则返回小数部分的长度,否则返回整数的长度。
票数 4
EN

Stack Overflow用户

发布于 2016-08-24 10:49:12

您需要将正则表达式的各个部分分组,可能如下所示

代码语言:javascript
复制
import re

def repl(m):
    if m.group(1) is None: #int
        return ("INT_%i"%len(m.group(2)))        
    else: #float
        return ("FLT_%i"%(len(m.group(2))))

input_string = "高露潔光感白輕悅薄荷牙膏100   79.80"

numbers = re.sub(r'[-+]?([0-9]*\.)?([0-9]+)([eE][-+]?[0-9]+)?',repl,input_string)        

print(numbers)
  • 组0是匹配的整个字符串(可用于放入floatint)。
  • 组1是..本身之前的任何数字,如果存在,则为None
  • 组2是.后面的所有数字,如果它存在,则它只是所有的数字。
  • 组3是指数部分,如果存在其他None的话

您可以从它获得一个python编号

代码语言:javascript
复制
def parse(m):
    s=m.group(0)
    if m.group(1) is not None or m.group(3) is not None: # if there is a dot or an exponential part it must be a float
        return float(s)
    else:
        return int(s)
票数 2
EN

Stack Overflow用户

发布于 2016-08-24 10:54:59

您可能正在寻找类似下面的代码(当然还有其他方法)。这一次只是从你正在做的事情开始,并展示了它是如何完成的。

代码语言:javascript
复制
import re
input_string = u"高露潔光感白輕悅薄荷牙膏100   79.80"

numbers = re.finditer(r'[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?',input_string)

s = input_string
for m in list(numbers)[::-1]:
    num = m.group(0)
    if '.' in num:
        s = "%sFLT_%s%s" % (s[:m.start(0)],str(len(num)-num.index('.')-1),s[m.end(0):])
    else:
        s = "%sINT_%s%s" % (s[:m.start(0)],str(len(num)), s[m.end(0):])
print(s)

这看起来可能有点复杂,因为确实有几个简单的问题要解决。

例如,您的初始regex同时找到了ints和浮动,但是您需要在之后应用完全不同的替换。如果你一次只做一件事,这就简单多了。但是,由于浮点数的一部分可能看起来像一个int,同时做任何事情可能不是一个坏主意,你只需要明白这将导致第二次检查来区分这两种情况。

另一个更根本的问题是,实际上,不能在python中替换任何。Python字符串是不可修改的对象,因此您必须复制。这是好的,因为格式的改变可能需要插入或删除字符和内部替换将是没有效率的。

最后要考虑的问题是,替换必须向后进行,因为如果更改字符串的开头,匹配位置也会发生变化,下一个替换将不会在正确的位置。如果我们后退一步,一切都会好的。

当然,我同意使用re.sub()要简单得多。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39120783

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档