-1

I'd like to trim left/right the input_string before passing it to regex_match in the if statement and I've unsuccessfully tried the boost trim_right and trim_left, not sure how to solve it though.

How do I simply trim the inputs so that the first two inputs " 0 " and " 0.1 " would become valid numbers?

#include <string>
#include <boost/algorithm/string.hpp>

#include <iostream>
#include <regex>
#include <vector>
using namespace std;

int main() {
    vector<string> string_vector = {"   0  ","   0.1   ","abc","1 a","2e10","-90e3","1e","e3","6e-1","99e2.5","53.5e93","--6","-+3","95a54e53"};

    regex expression_two("^[+-]?(?:[0-9]*\\.[0-9]+|[0-9]+\\.[0-9]*|[0-9]+)[Ee][+-]?[0-9]+$|^[+-]?(?:[0-9]*\\.[0-9]+|[0-9]+\\.[0-9]*|[0-9]+)$|^[+-]?[0-9]+$");

    for (const auto &input_string: string_vector) {
        if (std::regex_match(input_string, expression_two))
            cout << "[0-9] Char Class: '" << input_string << "' is a valid number." << endl;
    }
    return 0;
}

Current Output

[0-9] Char Class: '2e10' is a valid number.
[0-9] Char Class: '-90e3' is a valid number.
[0-9] Char Class: '6e-1' is a valid number.
[0-9] Char Class: '53.5e93' is a valid number.

Desired Output

[0-9] Char Class: '  0  ' is a valid number.
[0-9] Char Class: '  0.1  ' is a valid number.
[0-9] Char Class: '2e10' is a valid number.
[0-9] Char Class: '-90e3' is a valid number.
[0-9] Char Class: '6e-1' is a valid number.
[0-9] Char Class: '53.5e93' is a valid number.
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Emma
  • 27,428
  • 11
  • 44
  • 69
  • 1
    Allow for spaces before and after the interesting pattern, `regex expression_two(R"aw(^ *([+-]?(?:[0-9]*\.[0-9]+|[0-9]+\.[0-9]*|[0-9]+)[Ee][+-]?[0-9]+|[+-]?(?:[0-9]*\.[0-9]+|[0-9]+\.[0-9]*|[0-9]+)|[+-]?[0-9]+) *$)aw");` – Eljay Oct 16 '19 at 16:29
  • 1
    You're welcome. Nathan's answer for trimming is spot on, as is the cross-reference to the other question. I use Boost, but some people find Boost to be a bit too big (or daunting?) to want it in their projects. – Eljay Oct 16 '19 at 16:38

1 Answers1

0

The biggest issue is that std::regex_match needs a persitant string object for the results to refer to. If you don't have that then after inspecting the results would be accessing a string that doesn't exist which is undefined behavior. That means you need to modify the loop to use trim_copy from What's the best way to trim std::string? like

for (const auto &input_string: string_vector) {
    auto trimmed = trim_copy(input_string);
    if (std::regex_match(trimmed, expression_two))
        cout << "[0-9] Char Class: '" << input_string << "' is a valid number." << endl;
}

This is going to cost you a copy, but it is the only way to do this without modifying the source data. If you can modify the source data then you can use

for (auto &input_string: string_vector) {
    if (std::regex_match(trim(input_string), expression_two))
        cout << "[0-9] Char Class: '" << input_string << "' is a valid number." << endl;
}

instead.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • 1
    @Emma Just change your for loop to the first one that I have in the answer, and copy the trim functions over from [here](https://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring). You can see it running [here](http://coliru.stacked-crooked.com/a/39ed0e0403501865) – NathanOliver Oct 16 '19 at 16:31