Python正则表达式:计算和替换数值

时间:2019-07-09 14:48:09

标签: python regex string numeric

我遇到了一个正则表达式问题,该问题似乎并不像我想的那么普遍:我想提取所有具有px单位的数值,进行一些计算,然后将新值重新注入到我的字符串中。我不想包含px字符串(请参见下面的示例),但是我可以使用其他方法来保留它们,或更改单位类型。

例如,将值乘以2.5:

来自"2px aperture 12px science 2.1px yummy cake"

我想要"5 aperture 30 science 5.25 yummy cake"

我编写了一个粗略的脚本,但是我没有得到足够的期望输出:

import re
my_string = "2px aperture 12px science 2.1px yummy cake"
nb_list= re.findall(r"([0-9.]+)px", my_string)
splitted_string = re.findall('.*?px', my_string)
print(f"splitted_string = {splitted_string}")
print(f"nb_list = {nb_list}")
new_list = []
for i in range(0, len(nb_list)):
  new_n = str(float(nb_list[i])*2.5)
  new_string = re.sub(r"[0-9.]+px", new_n, splitted_string[i])
  new_list.append(new_string)
new_list = ''.join(new_list)
print(f"new_list = {new_list}")

结果:

new_list = 5.0 aperture 30.0 science 5.25

我理解为什么会得到这个结果,但是我不知道要进行什么更改才能获得所需的输出。

1 个答案:

答案 0 :(得分:8)

只需在回调中使用re.sub

r = re.sub(
    r'(\d+(\.\d+)?)px\b',
    lambda m: '{:g}'.format(float(m.group(1)) * 2.5),
    s)

很容易将其扩展到多个单元,例如:

units = {
    'px': 2.5,
    'em': 4,
}

r = re.sub(
    fr'(\d+(\.\d+)?)({"|".join(units)})\b',
    lambda m: '{:g}'.format(float(m.group(1)) * units[m.group(3)]),
    s)