Good job
And there is already a good answer here!
I'm only commenting on your regular expression, even though I'm not so sure how your input ranges may look like. But, it would probably miss some edge cases. I'm assuming that these are all acceptable:
$80,000,000,000.00 - $90,000,000,000.00 per annum
$80,000,000 - $90,000,000 per annum
$80,000 - $90,000 per annum
$20 - $24.99 per hour
$20 - $24.99 per hour
$20 - $24.99 per hour
$20.00 - $24.99 per hour
and these are unacceptable:
$20.00 - $24.99 per day
$111,120.00 - $11,124.99 per week
$111,222,120.00 - $111,111,124.99 per month
You can see your own expression in this link:
- It would pass some cases that may not be desired, I guess.
- You also do not need to escape
.
and $
inside a character class:
Code
import re
def find_range(text: str) -> dict:
expression = r'^\s*\$([0-9]{1,3}(?:,[0-9]{1,3})*(?:\.[0-9]{1,2})?)\s*-\s*\$([0-9]{1,3}(?:,[0-9]{1,3})*(?:\.[0-9]{1,2})?)\s*per\s+(?:annum|hour)\s*$'
return re.findall(expression, text)
input_a = '$80,000 - $90,000 per annum'
input_b = '$20 - $24.99 per hour'
print(find_range(input_a))
If you wish to simplify/update/explore the expression, it's been explained on the top right panel of regex101.com. You can watch the matching steps or modify them in this debugger link, if you'd be interested. The debugger demonstrates that how a RegEx engine might step by step consume some sample input strings and would perform the matching process.
RegEx Circuit
jex.im visualizes regular expressions:

all_examples = [input1, input2]
and runfor input in all_examples:
- this way you can test code with all inputs without changing code. Eventually you could create list with input and expected outputsall_examples = [(input1, "80000", "90000"), (input2, "20", "24.99")]
and automatically check if results are correctfor input, expected_low, expected_hight in all_examples: ... low == expected_low ... high == expected_hight ...
\$\endgroup\$ – furas Jun 15 '20 at 1:47