Coverage for /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/site-packages/vfx_seqtools/parser.py: 100%
25 statements
« prev ^ index » next coverage.py v7.8.2, created at 2025-05-30 00:30 +0000
« prev ^ index » next coverage.py v7.8.2, created at 2025-05-30 00:30 +0000
1import re
4def replace_hash_and_at_with_framenumber(
5 input_string: str,
6 number: int,
7) -> str:
8 """
9 Replace '#' and '@' in the input string with integers.
11 '#' and '@' are replaced with the value of `number`,
12 """
14 def zero_padded_match(match: re.Match) -> str:
15 offset_match = re.match(r"(#+)([+-])(\d+)", match.group(0))
16 if offset_match:
17 offset = int(offset_match.group(3))
18 offset = abs(offset) if offset_match.group(2) == "+" else -abs(offset)
19 padding_length = len(offset_match.group(1))
20 # account for negative numbers and formatting
21 if number + offset < 0:
22 padding_length += 1
23 return f"{(number + offset):0{padding_length}}"
24 else:
25 padding_length = len(match.group(0))
26 # account for negative numbers and formatting
27 if number < 0:
28 padding_length += 1
29 return f"{number:0{padding_length}}"
31 def unpadded_match(match: re.Match) -> str:
32 offset_match = re.match(r"(@+)([+-])(\d+)", match.group(0))
33 if offset_match:
34 offset = int(offset_match.group(3))
35 offset = abs(offset) if offset_match.group(2) == "+" else -abs(offset)
36 return str(number + offset)
37 else:
38 return str(number)
40 # Replace '#' and '@' with the frame number
41 output_string = re.sub(r"(#+)([+-]\d+)?", zero_padded_match, input_string)
42 output_string = re.sub(r"(@+)([+-]\d+)?", unpadded_match, output_string)
44 return output_string