【问题标题】:Python regex : compute and replace numeric valuesPython 正则表达式:计算和替换数值
【发布时间】:2019-11-19 04:00:25
【问题描述】:

我有一个正则表达式问题,它似乎不像我想象的那么普遍:我想提取所有具有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

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

【问题讨论】:

  • new_n = str(float(nb_list[i])*2.5)之后尝试使用new_n = re.sub(r"(?<=\d)(.0)(?=[^\d])",'',new_n)
  • 试试re.sub(r"(\d+(?:\.\d+)?)px", lambda x: str(float(x.group(1))*2.5), my_string)。也许r"(\d+(?:\.\d+)?)px\b" 会更精确,因为px 将作为一个整体匹配。见ideone.com/68NH7f

标签: python regex string numeric


【解决方案1】:

只需将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)

【讨论】:

  • 直到关于{:g}。我总是这样做.rstrip('0').rstrip('.'),但这更短。赞成。
  • 这正是我想要做的!我没有考虑 re.sub 中的 lambda,也不知道 f+r 字符串。我仍然需要一些时间才能完全理解这一点,但这看起来简洁明了,非常感谢!
猜你喜欢
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 2012-06-17
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 2018-01-19
  • 2010-10-30
相关资源
最近更新 更多