why regular expression match result is empty

Viewed 37

this is code

#include <iostream>
#include <regex>

using namespace std;

static void search_by_regex(const char *regex_s,
                            const string &s)
{ // ①
  regex reg_ex(regex_s);
  smatch match_result; // ②
  cout.width(14);      // ③
  if (regex_search(s, match_result, reg_ex))
  {                                                               // ④
    cout << regex_s << ": \"" << match_result[0] << "\"" << endl; // ⑤
  }
}

int main()
{
  string s("_AaBbCcDdEeFfGg12345!@#$% \t"); // ⑥

  search_by_regex("[[:alnum:]]{5}", s); // ⑦
  search_by_regex("\\w{5,}", s);        // ⑧
  search_by_regex(R"(\W{3,5})", s);     // ⑨
  search_by_regex("[[:digit:]]*", s);   // ⑩
  search_by_regex(".+", s);             // ⑪
  search_by_regex("[[:lower:]]?", s);   // ⑫

  return 0;
}

this is output:

    [[:alnum:]]{5}: "AaBbC"
            \w{5,}: "_AaBbCcDdEeFfGg12345"
           \W{3,5}: "!@#$%"
      [[:digit:]]*: ""
                .+: "_AaBbCcDdEeFfGg12345!@#$%  "
      [[:lower:]]?: ""

I think the result is strange.

Why the result of a regular expression [[:digit:]]* match is empty?

Why the result of a regular expression [[:lower:]]* match is empty?

1 Answers

In short

With your current setup, you will return after your first match, as you did not set the global flag (/.../g). Consider the following tokens: ? or *. They will return a null match ("") if nothing matches immediately. Your regex, having such tokens, will return a null match if the first character does not match and the g flag is not set, which is the case. See the demonstration below using your example with interactive links for you to try and experiment.

Example using [[:lower:]]?:

The regex starts at the beginning of the line, and is looking for something that will match either a lower case, or nothing. The first character ('_') is not a lower case character, therefore it defaults to nothing (?). One of two things may happen next:

  1. Without the global flag enabled (/[[:lower:]]?/) the regex returns the match ("") as soon as found. See example on regex101.com or see the little purple-ish line at the start on the following figure:

Matching without the global flag on Regex101.com

  1. With the global flag enabled (/[[:lower:]]?/g), the regex continues to search for matches until the string runs out, then returns an array of matches. See example on regex101.com or see the multiple purple-ish lines (match end positions), and blue highlights (matches):

Matching using the global flag on Regex101.com

Hope this helps :)

Related