首页 > 解决方案 > 使用正则表达式添加前导零

问题描述

说我有一个字符串

'1 - hello.mp3'
'22 - hellox.mp3'
'223 - hellox.mp3'
'hellox.mp3'

我希望输出是

'001 - hello.mp3'
'022 - hellox.mp3'
'223 - hellox.mp3'
'hellox.mp3'

也就是说,如果起始是数字,则附加 0 使其成为三位数字。

有没有办法在python中使用正则表达式?

标签: pythonregexpython-3.x

解决方案


是的,正则表达式可以做到这一点。re.sub()与回调函数一起使用:

import re

def pad_number(match):
    number = int(match.group(1))
    return format(number, "03d")

fixed_text = re.sub(r"^(\d+)", pad_number, text)

我使用的模式^(\d+)匹配 1 个或多个数字(\d是一个数字,+将至少匹配一次,但将包含所有后续数字),但仅在字符串的开头(^这里是“文本开头”锚点)。

然后,对于每个匹配的模式,pad_number()调用该函数,并且该函数返回的字符串用于替换匹配的模式。因为该模式使用一个捕获组(和之间的所有内容(都是)这样一个组),所以该函数可以通过调用来访问匹配的数字match.group(1)

该函数将数字转换为整数,然后使用该format()函数将该整数转换回文本,但这一次是一个 0 填充的数字,宽度为 3 个字符;这就是03格式化指令format()要产生的内容。

请注意,该模式可以匹配更多数字,但限制它们没有多大意义,除非您想要限制一个严格的上限(此时您还需要添加对下一个字符不是数字的限制) . 该format(number, "03d")指令产生一个至少3 位宽的数字,但可以处理更长的值。

演示:

>>> import re
>>> samples = [
...     '1 - hello.mp3',
...     '22 - hellox.mp3',
...     '223 - hellox.mp3',
...     'hellox.mp3',
... ]
>>> def pad_number(match):
...     number = int(match.group(1))
...     return format(number, "03d")
...
>>> for sample in samples:
...     result = re.sub(r"^(\d+)", pad_number, sample)
...     print(f"{sample!r:20} -> {result!r:20}")
...
'1 - hello.mp3'      -> '001 - hello.mp3'
'22 - hellox.mp3'    -> '022 - hellox.mp3'
'223 - hellox.mp3'   -> '223 - hellox.mp3'
'hellox.mp3'         -> 'hellox.mp3'

同样,请注意此方法不会对开头有 4 个或更多数字的字符串进行特殊处理;您只需获得更长的数字序列:

>>> re.sub(r"^(\d+)", pad_number, "4281 - 4 digits")
'4281 - 4 digits'
>>> re.sub(r"^(\d+)", pad_number, "428117 - 6 digits")
'428117 - 6 digits'

即使我们将\d模式限制为最多匹配 3 位数字(例如 with \d{1,3}),也会发生这种情况。

如果您想使填充宽度可配置,您可以将所有内容放在嵌套函数中并使用字符串格式。你真的不需要

import re

def pad_leading_number(text, width):
    def pad_number(match):
        number = int(match.group(1))
        return format(number, f"0{width}d")

    return re.sub(fr"^(\d+)", pad_number, text)

演示:

>>> pad_leading_number("22 - hellox.mp3", 3)
'022 - hellox.mp3'
>>> pad_leading_number("22 - hellox.mp3", 7)
'0000022 - hellox.mp3'

推荐阅读