I really hope it is just puzzler and no one will use regex for this problem in real world. Proper solution would be converting number from string to numeric type like BigInteger
. This should allow us to check its range using proper methods or operators, like compareTo
, >
, <
.
To make life easier you can use this page (dead link) to generate regex for ranges. So regex for range 0
- 2147483647
can look like
([0-9]{1,9}|1[0-9]{9}|2(0[0-9]{8}|1([0-3][0-9]{7}|4([0-6][0-9]{6}|7([0-3][0-9]{5}|4([0-7][0-9]{4}|8([0-2][0-9]{3}|3([0-5][0-9]{2}|6([0-3][0-9]|4[0-7])))))))))
(friendlier way)
(
[0-9]{1,9}|
1[0-9]{9}|
2(0[0-9]{8}|
1([0-3][0-9]{7}|
4([0-6][0-9]{6}|
7([0-3][0-9]{5}|
4([0-7][0-9]{4}|
8([0-2][0-9]{3}|
3([0-5][0-9]{2}|
6([0-3][0-9]|
4[0-7]
)))))))))
and range 0
- 2147483648
([0-9]{1,9}|1[0-9]{9}|2(0[0-9]{8}|1([0-3][0-9]{7}|4([0-6][0-9]{6}|7([0-3][0-9]{5}|4([0-7][0-9]{4}|8([0-2][0-9]{3}|3([0-5][0-9]{2}|6([0-3][0-9]|4[0-8])))))))))
So we can just combine these ranges and write it as
range of 0-2147483647
OR
"-" range of 0-2147483648
which will give us
([0-9]{1,9}|1[0-9]{9}|2(0[0-9]{8}|1([0-3][0-9]{7}|4([0-6][0-9]{6}|7([0-3][0-9]{5}|4([0-7][0-9]{4}|8([0-2][0-9]{3}|3([0-5][0-9]{2}|6([0-3][0-9]|4[0-7])))))))))|-([0-9]{1,9}|1[0-9]{9}|2(0[0-9]{8}|1([0-3][0-9]{7}|4([0-6][0-9]{6}|7([0-3][0-9]{5}|4([0-7][0-9]{4}|8([0-2][0-9]{3}|3([0-5][0-9]{2}|6([0-3][0-9]|4[0-8])))))))))
.
[edit]
Since Bohemian noticed in his comment final regex can be in form -?regex1|-2147483648
so here is little shorter version (also changed [0-9]
to d
)
^-?(d{1,9}|1d{9}|2(0d{8}|1([0-3]d{7}|4([0-6]d{6}|7([0-3]d{5}|4([0-7]d{4}|8([0-2]d{3}|3([0-5]d{2}|6([0-3]d|4[0-7])))))))))$|^-2147483648$
If you will use it in Java String#matches(regex)
method on each line you can also skip ^
and $
parts since they will be added automatically to make sure entire string matches regex.
I know this regex is very ugly, but just shows why regex is not good tool for range validation.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…