Skip to content

Commit 8512b90

Browse files
committed
Enhanced to support negative values for ranges.
1 parent 1cd4c84 commit 8512b90

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

range_regex/range_regex.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import math
2+
13
# coding=utf8
24

35
# Split range to ranges that has its unique pattern.
@@ -19,14 +21,38 @@ def regex_for_range(min_, max_):
1921
> regex_for_range(12, 345)
2022
'1[2-9]|[2-9]\d|[1-2]\d{2}|3[0-3]\d|34[0-5]'
2123
"""
24+
positive_subpatterns = []
25+
negative_subpatterns = []
26+
27+
if min_ < 0:
28+
min__ = 1
29+
if max_ < 0:
30+
min__ = abs(max_)
31+
max__ = abs(min_)
32+
33+
negative_subpatterns = split_to_patterns(min__, max__)
34+
min_ = 0
35+
36+
if max_ >= 0:
37+
positive_subpatterns = split_to_patterns(min_, max_)
38+
39+
negative_only_subpatterns = ['-' + val for val in negative_subpatterns if val not in positive_subpatterns]
40+
positive_only_subpatterns = [val for val in positive_subpatterns if val not in negative_subpatterns]
41+
intersected_subpatterns = ['-?' + val for val in negative_subpatterns if val in positive_subpatterns]
42+
43+
subpatterns = negative_only_subpatterns + intersected_subpatterns + positive_only_subpatterns
44+
return '|'.join(subpatterns)
45+
46+
47+
def split_to_patterns(min_, max_):
2248
subpatterns = []
2349

2450
start = min_
2551
for stop in split_to_ranges(min_, max_):
2652
subpatterns.append(range_to_pattern(start, stop))
2753
start = stop + 1
2854

29-
return '|'.join(subpatterns)
55+
return subpatterns
3056

3157

3258
def split_to_ranges(min_, max_):

range_regex/tests.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,28 @@ def _verify_range(self, regex, min_, max_, from_min_, to_max_):
1212

1313
def test_quality(self):
1414
self.assertEqual(regex_for_range(1, 1), '1')
15+
self.assertEqual(regex_for_range(0, 1), '[0-1]')
16+
self.assertEqual(regex_for_range(-1, -1), '-1')
17+
self.assertEqual(regex_for_range(-1, 0), '-1|0')
18+
self.assertEqual(regex_for_range(-1, 1), '-1|[0-1]')
19+
self.assertEqual(regex_for_range(-4, -2), '-[2-4]')
20+
self.assertEqual(regex_for_range(-3, 1), '-[1-3]|[0-1]')
21+
self.assertEqual(regex_for_range(-2, 0), '-[1-2]|0')
22+
self.assertEqual(regex_for_range(0, 2), '[0-2]')
23+
self.assertEqual(regex_for_range(-1, 3), '-1|[0-3]')
1524
self.assertEqual(regex_for_range(65666, 65667), '6566[6-7]')
1625
self.assertEqual(regex_for_range(12, 3456), r'1[2-9]|[2-9]\d|[1-9]\d{2}|[1-2]\d{3}|3[0-3]\d{2}|34[0-4]\d|345[0-6]')
1726
self.assertEqual(regex_for_range(1, 19), r'[1-9]|1\d')
1827
self.assertEqual(regex_for_range(1, 99), r'[1-9]|[1-9]\d')
1928

29+
def test_optimization(self):
30+
self.assertEqual(regex_for_range(-9, 9), r'-[1-9]|\d')
31+
self.assertEqual(regex_for_range(-19, 19), r'-[1-9]|-?1\d|\d')
32+
self.assertEqual(regex_for_range(-29, 29), r'-[1-9]|-?[1-2]\d|\d')
33+
self.assertEqual(regex_for_range(-99, 99), r'-[1-9]|-?[1-9]\d|\d')
34+
self.assertEqual(regex_for_range(-999, 999), r'-[1-9]|-?[1-9]\d|-?[1-9]\d{2}|\d')
35+
self.assertEqual(regex_for_range(-9999, 9999), r'-[1-9]|-?[1-9]\d|-?[1-9]\d{2}|-?[1-9]\d{3}|\d')
36+
2037
def test_equal(self):
2138
regex = bounded_regex_for_range(1, 1)
2239
self._verify_range(regex, 1, 1, 0, 100)

0 commit comments

Comments
 (0)