Skip to content

Instantly share code, notes, and snippets.

@internetimagery
Last active April 24, 2023 11:20
Show Gist options
  • Save internetimagery/f145e9f1acaf5723cde9e7e49e327bd2 to your computer and use it in GitHub Desktop.
Save internetimagery/f145e9f1acaf5723cde9e7e49e327bd2 to your computer and use it in GitHub Desktop.
Simple range expression parsing.
import re
def parse_compact_range(expression):
numbers = set()
for match_ in re.finditer(r"(?:(\d+)\s*\-\s*(\d+)|(\d+))\s*(?:,|$)", expression):
start, stop, exact = match_.group(1,2,3)
if exact is not None:
numbers.add(int(exact))
else:
begin, end = sorted(map(int, (start, stop)))
numbers.update(range(begin, end + 1))
return sorted(numbers)
def format_compact_range(*numbers):
if not numbers:
return ""
tokens = []
nums = sorted(set(numbers))
start = last_num = nums[0]
create_token = lambda: tokens.append(
("{}".format if start == last_num else "{}-{}".format)(start, last_num)
)
for num in nums[1:]:
if num - 1 != last_num:
create_token()
start = num
last_num = num
create_token()
return ",".join(tokens)
if __name__ == "__main__":
assert [3,6,9] == parse_compact_range("3,6,9")
assert [1,2,3] == parse_compact_range("1-3")
assert [1,2,5,6,9] == parse_compact_range("1 - 2, 5 - 6, 9")
assert [1,2,3] == parse_compact_range("3-1")
assert [1,2,3,4] == parse_compact_range("1-4, 3, 2, 4-1")
assert [] == parse_compact_range("")
assert format_compact_range(3,6,9) == "3,6,9"
assert format_compact_range(1,2,3) == "1-3"
assert format_compact_range(1,2,5,6,9) == "1-2,5-6,9"
assert format_compact_range(1) == "1"
assert format_compact_range(1,2,3,4) == "1-4"
assert format_compact_range() == ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment