C ++ regex_match doesn't work

Here is part of my code

bool CSettings::bParseLine ( const char* input )
{
    //_asm INT 3


    std::string line ( input );
    std::size_t position = std::string::npos, comment;

    regex cvarPattern ( "\\.([a-zA-Z_]+)" );
    regex parentPattern ( "^([a-zA-Z0-9_]+)\\." );
    regex cvarValue ( "\\.[a-zA-Z0-9_]+[ ]*=[ ]*(\\d+\\.*\\d*)" );
    std::cmatch matchedParent, matchedCvar;


    if ( line.empty ( ) )
        return false;

    if ( !std::regex_match ( line.c_str ( ), matchedParent, parentPattern ) )
        return false;

    if ( !std::regex_match ( line.c_str ( ), matchedCvar, cvarPattern ) )
        return false;
...
}

      

I am trying to split with it the lines I read from the lines of the file that look like this:

foo.bar = 15
baz.asd = 13
ddd.dgh = 66

      

and I want to extract parts from it - for example. for 1st line foo.bar = 15, I want to get something like:

a = foo
b = bar
c = 15

      

but now the regex always returns false, i tested it on many online riggers and even visual studio and it works fine, i need some other syntax for c ++ regex_match? I am using visual studio 2013 community

+3


source to share


2 answers


The problem is that std :: regex_match must match the entire string, but you are trying to match only part of it.

You need to either use std :: regex_search or change your regex to match all three parts at the same time:

#include <regex>
#include <string>
#include <iostream>

const auto test =
{
      "foo.bar = 15"
    , "baz.asd = 13"
    , "ddd.dgh = 66"
};

int main()
{
    const std::regex r(R"~(([^.]+)\.([^\s]+)[^0-9]+(\d+))~");
    //                     (  1  )  (   2  )       ( 3 ) <- capture groups

    std::cmatch m;

    for(const auto& line: test)
    {
        if(std::regex_match(line, m, r))
        {
            // m.str(0) is the entire matched string
            // m.str(1) is the 1st capture group
            // etc...
            std::cout << "a = " << m.str(1) << '\n';
            std::cout << "b = " << m.str(2) << '\n';
            std::cout << "c = " << m.str(3) << '\n';
            std::cout << '\n';
        }
    }
}

      



Regular expression: https://regex101.com/r/kB2cX3/2

Output:

a = foo
b = bar
c = 15

a = baz
b = asd
c = 13

a = ddd
b = dgh
c = 66

      

+8


source


To focus on templates regex

, I would rather use raw string literals in C ++:

regex cvarPattern ( R"rgx(\.([a-zA-Z_]+))rgx" );
regex parentPattern ( R"rgx(^([a-zA-Z0-9_]+)\.)rgx" );
regex cvarValue ( R"rgx(\.[a-zA-Z0-9_]+[ ]*=[ ]*(\d+\.*\d*))rgx" );

      

Everything between the delimiters rgx(

)rgx

does not need additional escaping for C ++ char characters.


Actually what you wrote in your question is similar to those regexes I wrote as string literals.
You probably just meant something like

regex cvarPattern ( R"rgx(.([a-zA-Z_]+))rgx" );
regex parentPattern ( R"rgx(^([a-zA-Z0-9_]+).)rgx" );
regex cvarValue ( R"rgx(.[a-zA-Z0-9_]+[ ]*=[ ]*(\d+(\.\d*)?))rgx" );

      



I didn't dig deeper, but now I am not getting all those escaped characters in your regex patterns.


Regarding your question in the comment, you can use a selection of suitable submatrix groups and check which one was applied in the match structure:

regex cvarValue ( 
   R"rgx(.[a-zA-Z0-9_]+[ ]*=[ ]*((\d+)|(\d+\.\d?)|([a-zA-Z]+)){1})rgx" );
                             // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

      

You probably do not need these regular expressions cvarPattern

and parentPattern

to check for other (more detailed) ideas about the appropriate template.

+3


source







All Articles