Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ regex_match not working

Tags:

c++

regex

c++11

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 try to separate with it lines which I read from file - lines look like:

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

and I want to extract parts from it - e.g. for 1st line foo.bar = 15, I want to end up with something like:

a = foo
b = bar
c = 15

but now, regex is returning always false, I tested it on many online regex checkers, and even in visual studio, and it's working great, do I need some different syntax for C++ regex_match? I'm using visual studio 2013 community

like image 600
mlgpro Avatar asked May 25 '15 19:05

mlgpro


People also ask

What does Regex_match return in C++?

regex_match() This function returns true if the given expression matches the string. Otherwise, the function returns false.

What is\\ in regular expression?

You also need to use regex \\ to match "\" (back-slash). Regex recognizes common escape sequences such as \n for newline, \t for tab, \r for carriage-return, \nnn for a up to 3-digit octal number, \xhh for a two-digit hex code, \uhhhh for a 4-digit Unicode, \uhhhhhhhh for a 8-digit Unicode.

Is std RegEx slow?

The current std::regex design and implementation are slow, mostly because the RE pattern is parsed and compiled at runtime.

How to use import re in Python?

Python has a module named re to work with RegEx. Here's an example: import re pattern = '^a...s$' test_string = 'abyss' result = re. match(pattern, test_string) if result: print("Search successful.") else: print("Search unsuccessful.")


1 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 alter your regular expression to match all three parts at once:

#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
like image 182
Galik Avatar answered Oct 04 '22 22:10

Galik