用相应的减法结果替换字符串中的数字

n61*_*007 4 python regex string parsing replace

我有一个像这样的字符串:

"foo 15 bar -2hello 4 asdf+2"
Run Code Online (Sandbox Code Playgroud)

我想得到:

"foo 14 bar -3hello 3 asdf+1"
Run Code Online (Sandbox Code Playgroud)

我想将每个数字(数字序列替换为有符号的基数为10的整数)替换为每个数字执行减法的结果,每个数字一个.

我写了一个~50 LOC函数,它迭代字符,分隔符号,数字和其他文本,应用函数并重新组合部分.虽然它有一个问题,但我对这个问题的意图不是审查它.相反,我试图问,解决这个问题的pythonic方法是什么,是否有更简单的方法?

作为参考,这是我的功能与已知问题,但我的意图不是要求审查,而是找到最pythonic方式.

编辑回答明智评论詹恩Karila:

  • 首选:保留标志如果给予:+2应该成为+1
  • 首选:零没有迹象:+1应该成为0
  • 首选:没有空格:asdf - 4成为asdf - 3
  • 要求:只有一个标志:-+-2成为-+-3

在这里编辑热门需求是我的错误代码:)

免责声明:请注意我对修复此代码不感兴趣.我在问是否有比我更好的方法.

def apply_to_digits(some_str,handler):
    sign = "+"
    started = 0
    number = []
    tmp = []
    result = []
    for idx,char in enumerate(some_str):
        if started:
            if not char.isdigit():
                if number:
                    ss = sign + "".join(number)
                    rewritten = str(handler(int(ss)))
                    result.append(rewritten)
                elif tmp:
                    result.append("".join(tmp))
                number = []
                tmp = []
                sign = "+"
                started = 0
                # char will be dealt later
            else:
                number.append(char)
                continue
        if char in "-+":
            sign = char
            started = 1
            if tmp:
                result.append("".join(tmp))
                tmp = []
            tmp.append(char)
            continue
        elif char.isdigit():
            started = 1
            if tmp:
                result.append("".join(tmp))
                tmp = []
            number.append(char)
        else:
            tmp.append(char)
    if number:
        ss = sign + "".join(number)
        rewritten = str(handler(int(ss)))
        result.append(rewritten)
    if tmp:
        result.append("".join(tmp)), tmp
    return "".join(result)
#
Run Code Online (Sandbox Code Playgroud)

免责声明:请注意我对修复此代码不感兴趣.我在问是否有比我更好的方法.

Mic*_*x2a 12

您可以尝试使用正则表达式,并使用re.sub:

>>> pattern = "(-?\d+)|(\+1)"
>>> def sub_one(match):
        return str(int(match.group(0)) - 1)

>>> text = "foo 15 bar -2hello 4 asdf+2"
>>> re.sub(pattern, sub_one, text)
'foo 14 bar -3hello 3 asdf+1'
Run Code Online (Sandbox Code Playgroud)

正则表达式(-?\d+)|(\+1)将捕获可选-符号和一个或多个数字,或文字序列+1.这样,正则表达式将确保转换数字时的所有要求都能正常工作.

正则表达式(-?\d+)本身在大多数情况下都是正确的,但是(\+1)存在以确保字符串+1始终转换为零,没有符号.如果你改变主意,想要+1转换为+0,那么你只能使用正则表达式的第一部分:(-?d+).

如果你想要的话,你可以将这一切压缩成一个单行:

def replace_digits(text):
    return re.sub("(-?\d+)|(\+1)", lambda m: str(int(m.group(0)) - 1), text)
Run Code Online (Sandbox Code Playgroud)