1

How to perform range checking using regular expressions?

Take a 4-bit number (i.e. "dddd") as an example, how can I check whether it is within given range, say [1256-4350] or not?

herohuyongtao
  • 49,413
  • 29
  • 133
  • 174

4 Answers4

4

To check whether the input is a 4 digit number use regex_match, and then convert the string to an integer using std::stoi to check the range.

std::regex expr(R"(\d{4})");

if(std::regex_match(input, expr)) {
    int num = std::stoi(input);

    if(num >= 1256 && num <= 4350) {
        // input is within range
    }
}   

As Jarod42 mentions in the comments, since you've already validated the input is a 4 digit number, it's not necessary to convert it to an integer. Assuming input is an std::string, this would work too

if(input >= "1256" && input <= "4350") {
    // input is within range
}
Praetorian
  • 106,671
  • 19
  • 240
  • 328
3

Using this website, the regex you are after should look like this: ^(125[6-9]|12[6-9][0-9]|1[3-9][0-9]{2}|[23][0-9]{3}|4[0-2][0-9]{2}|43[0-4][0-9]|4350)$.

That being said, I think it is far more readable and maintainable do break it into two steps, first validate the data type and then the range. (What happens when the range shifts? Your entire regex will most likely be made useless).

npinti
  • 51,780
  • 5
  • 72
  • 96
  • What will the `regex` be like if we already know it's already a 4-bit number (only need to verify its range)? – herohuyongtao Feb 13 '14 at 13:51
  • 1
    @herohuyongtao: Regular expression match patterns and are not used for mathematical operations such as range checks. The regular expression will change depending on the new range. Regardless, the resulting regex will be much less readable than breaking the entire process in two. – npinti Feb 13 '14 at 13:53
  • I see, just like @Praetorian's answer. Thanks. – herohuyongtao Feb 13 '14 at 13:55
  • 1
    @herohuyongtao: Yes, if you notice, if the range changes, only the latter part of Praeterian's answer needs to be changed, and what the code does is much more clear than the regex above. – npinti Feb 13 '14 at 13:59
2

Here is a great site that will give you the answer.

For your example:

(\b(125[6-9]|12[6-9][0-9]|1[3-9][0-9]{2}|[23][0-9]{3}|4[0-2][0-9]{2}|43[0-4][0-9]|4350)\b

GabiMe
  • 18,105
  • 28
  • 76
  • 113
1

Yeah, I know this will work. I just want to check if we can verify it's indeed a number and at the same time check its range using

Okay... But don't use regex for this task. It's a terrible choice.

#include <iostream>
#include <sstream>
using namespace std;


bool is_number_in_range(string s) {
    istringstream str(s);
    int i; char c;
    str >> i;
    if( str.fail() ) return false;
    return i>=1256 && i<=4350 && str.eof();
}

int main() {
    cout<< is_number_in_range("0") << '\n'<<
        is_number_in_range("1234") << '\n'<<
        is_number_in_range("1256") << '\n'<<
        is_number_in_range("2000") << '\n'<<
        is_number_in_range("4350") << '\n'<<
        is_number_in_range("5000") << '\n'<<
        is_number_in_range("abcd") << '\n'<<
        is_number_in_range("1234.0") << '\n';


    return 0;
}

see it live

KitsuneYMG
  • 12,753
  • 4
  • 37
  • 58