Parsing pairs of a number or number range I need to process an array of number pairs. Here are the constraints on the pairs:


The second item may be missing, in this case 0 will be used as second item - - 38 is the same as 38,0 
The pair items may be a number, or a range - 149,0, 149,[3,7], [5,9],11, [3,6],[2,9], [4,8]
The range may be inclusive or exclusive - [8,11], [3,9), (4,10]
There may be any number of spaces between items - [ 3 , 6 ]
The second item may be &gt;=0, this is the same as bullet #1 - 36, &gt;=0


Why do I need the ranges? If I have, say, 149,[3,5], then I need to have 3 pairs - 149,3, 149,4, 149,5. If I have [8,10], then the pairs are 8,0, 9,0, 10,0. You get the idea.

I wrote a regex to get the items from the input. I think regex is not the best choice here, maybe I'll change it. Here's my program:

#include &lt;string&gt;
#include &lt;regex&gt;
#include &lt;vector&gt;

using intRange = std::pair&lt;int, int&gt;;
std::vector&lt;std::pair&lt;int, int&gt;&gt; pairs;

intRange getRange(const std::string &amp;value1, const std::string &amp;value2, const std::string &amp;value3)
{
    if (value1.length())
        return intRange(std::stoi(value1), std::stoi(value1));

    if (value2.length() &amp;&amp; value3.length())
    {
        const short startIncrement = value2.front() == '(' ? 1 : 0;
        const short endDecrement = value3.back() == ')' ? 1 : 0;

        // remove the parentheses
        std::string val2 = value2, val3 = value3;
        val2.replace(0, 1, std::string{});
        val3.pop_back();

        return intRange(std::stoi(val2) + startIncrement, std::stoi(val3) - endDecrement);
    }

    return {};
}

bool parseRange(const std::string &amp;input)
{
    pairs.clear();

    static const std::regex rx{ R"numrange(\s*(?:(\s*\d+\s*)|([\[\(]\s*\d+)\s*,\s*(\d+\s*[\]\)]))(?:,\s*(?:(\d+\s*)|\s*([\[\(]\d+)\s*,\s*(\d+\s*[\]\)])|(\s*&gt;\s*=\s*0\s*)))?\s*)numrange" };

    std::smatch matches;
    if (std::regex_match(input, matches, rx))
    {
        // if 1st (4th) match group exists, first (second) item is a single number
        // if 2nd and 3rd (5th and 6th) match groups exist, first (second) item is a range
        // if neither 4th nor 5th and 6th groups exist, then second item isn't specified, and default value (0) is used 
        auto firstRange = getRange(matches[1], matches[2], matches[3]);
        auto secondRange = getRange(matches[4], matches[5], matches[6]);

        // save all pairs
        for (auto first = firstRange.first; first &lt;= firstRange.second; ++first)
            for (auto second = secondRange.first; second &lt;= secondRange.second; ++second)
                pairs.emplace_back(first, second);
    }
    else
        return false;

    return true;
}

int main()
{
    std::vector&lt;std::string&gt; inputs = {
        "38",
        "149,0",
        "149,[3,7]",
        "[5,9],11",
        "[3,6],[2,9]",
        "[4,8]",
        "[3,9)",
        "(4,10]",
        "[ 3 , 6 ]",
        "36, &gt;= 0"
    };

    for (const auto &amp;input : inputs)
    {
        if (parseRange(input))
        {
            std::cout &lt;&lt; "input: " &lt;&lt; input &lt;&lt; '\n';
            for (const auto &amp;pair : pairs)
                std::cout &lt;&lt; pair.first &lt;&lt; ", " &lt;&lt; pair.second &lt;&lt; '\n';
            std::cout &lt;&lt; "-------------------\n";
        }
        else
        {
            std::cout &lt;&lt; "Error occurred.";
            return -1;
        }
    }

    std::cin.get();
}


I think there is room for improvement for this code. Please let me know where I can improve. Thanks.
Just answering this question since it is unanswered. Hope, it would help: 

Since your code is mainly about RegEx, which you'd most likely know that you can use this tool:


Your original RegEx based on an exact match method takes 265 steps and 1ms to match your 10 inputs, which is good. 

\s*(?:(\s*\d+\s*)|([\[\(]\s*\d+)\s*,\s*(\d+\s*[\]\)]))(?:,\s*(?:(\d+\s*)|\s*([\[\(]\d+)\s*,\s*(\d+\s*[\]\)])|(\s*&gt;\s*=\s*0\s*)))?\s*

Sometimes, exact match may not be necessary, not sure about your case or if you might have certain boundaries, but maybe you could use a faster RegEx with a lower number of iterations, maybe something similar to this, if you are not looking for an exact match, which is pretty fast and might match your 10 inputs with only 50 steps:  

^[0-9\,\[\]\(\) &gt;=]*$



The drawback of this method is that it is based on your input characters, i.e., numbers, [, ], (, ), ,, space and >=.