图像序列中的文件通常如下所示:image.001.png,其中" 001"是此图像的帧编号。我正在尝试构建一个将在组中捕获的序列模式:1)帧号之前的所有内容,2)帧号,3)扩展名。
我对正则表达式完全陌生,而且我无法创建一个可以在我能想到的每种可能情况下工作的模式。到目前为止,这里是我所知道的可能情况,以及我想在下面的括号中捕获的内容:
img123.png
(img) (123) (png)
img.123.png
(img.) (123) (png)
img_v01_1234.png
(img_v01_) (1234) (png)
img01_123.png
(img01_) (123) (png)
img.001.123.png
(img.001.) (123) (png)
img 001.12.png
(img 001.) (12) (png)
我只知道我可以做出两个稳定的假设。 1)将有一个3-4个字符的文件扩展名(显然前面有一个句点)。 2)帧号始终位于文件扩展名之前。除此之外,它是一个免费的所有人,这是我被绊倒的地方。有时文件名中还有其他数字,有时它们之前/之后有句号(或其他字符)。所以本质上我需要能够捕获一系列大于0的数字的LAST实例(希望这是有意义的)。
我发现(.{3,4})$
将匹配文件扩展名,而([0-9]+)
将匹配任何数字序列。所以下面的内容让我几乎到了那里,我只是错过了序列号之前的所有内容:([0-9]+)\.(.{3,4})$
答案 0 :(得分:0)
您可以尝试以下模式:
^([\w. ]+)(?<!\d)(\d+)\.(\w+)$
根据需要匹配所有测试用例:
因此,如果没有前缀的文件名是可能的,那么你应该确实应用修改后的模式:
^(.*)(?<!\d)(\d+)\.(\w+)$
答案 1 :(得分:0)
你目前的模式非常好。要获得之前的部分,您可以将所有字符与惰性量词(?
)匹配,以便在达到数字时停止。所以完整的模式是:
^(.+?)([0-9]+)\.(.{3,4})$
这适用于所有角色,在我看来比负面的背后更简单。
试验:
import re
tests = '''\
img123.png
(img) (123) (png)
img.123.png
(img.) (123) (png)
img_v01_1234.png
(img_v01_) (1234) (png)
img01_123.png
(img01_) (123) (png)
img.001.123.png
(img.001.) (123) (png)
img 001.12.png
(img 001.) (12) (png)'''
for pair in tests.split('\n\n'):
filename, output = pair.strip().splitlines()
assert (list(re.match(r'^(.+?)([0-9]+)\.(.{3,4})$', filename).groups()) ==
re.findall(r'\((.+?)\)', output))