与查找和替换相乘

时间:2010-04-23 18:31:48

标签: python regex sed

可以使用正则表达式来执行算术运算吗?例如找到文件中的所有数字并将它们乘以标量值。

6 个答案:

答案 0 :(得分:8)

您可以使用带有回调的re.sub()来实现此目的:

import re

def repl(matchobj):
  i = int(matchobj.group(0))
  return str(i * 2)

print re.sub(r'\d+', repl, '1 a20 300c')

输出:

2 a40 600c

来自文档:

  

re.sub(pattern,repl,string [,   算])

     

如果repl是一个函数,则调用它   对于每个不重叠的事件   模式。该功能需要一个   单个匹配对象参数,和   返回替换字符串。

答案 1 :(得分:4)

在perl中,您可以使用/ e修饰符执行此操作。这导致表达式的替换部分被评估。假设$ line包含文件的一行

 my $scalar= 4;
 $line =~ s/([\d]+)/$1*$scalar/ge;

将此应用于每一行都可以帮到您。例如,将其应用于 $ line包含“foo2 bar25 baz”,将其转换为“foo8 bar100 baz”

答案 2 :(得分:2)

我准备了一个小脚本,它使用re.finditer来查找所有整数(你可以更改正则表达式,以便它可以处理浮点数或科学记数法),然后使用map返回一个列表缩放数字。

import re

def scale(fact):
    """This function returns a lambda which will scale a number by a                           
    factor 'fact'"""
    return lambda val: fact * val

def find_and_scale(file, fact):
    """This function will find all the numbers (integers) in a file and                        
    return a list of all such numbers scaled by a factor 'fact'"""
    num = re.compile('(\d+)')
    scaling = scale(fact)
    f = open(file, 'r').read()
    numbers = [int(m.group(1)) for m in num.finditer(f)]
    return map(scaling, numbers)

if __name__ == "__main__":
    import sys
    if len(sys.argv) != 3:
        print "usage: %s file factor" % sys.argv[0]
        sys.exit(-1)
    numbers = find_and_scale(sys.argv[1], int(sys.argv[2]))
    for number in numbers:
        print "%d " % number

如果您希望将file的数字缩放fact因子,则可以从命令行调用脚本python script.py file fact,它将打印到STDOUT所有缩放的数字。当然,如果你想要,你可以做一些更有用的事情......

答案 3 :(得分:1)

正则表达式本身不能 - 它们都是关于文本的 - 所以sed不能直接。但是,在python或perl这样的完整脚本语言中做这样的事情很容易。

答案 4 :(得分:1)

对于那些怀疑sed可以做算术的人,我提供这个counter-exampleThis one甚至更加狂野。

答案 5 :(得分:-1)

Ayman Hourieh的答案可以简化为更简单一点,而且更具可读性:

>>> import re
>>> repl = lambda m: str(int(m.group(0)) * 2)
>>> print re.sub(r'\d+', repl, '1 a20 300c')
2 a40 600c