title: std::regex and ignoring flags
body: <p>After learning basic <a href="/questions/tagged/c%2b%2b" class="post-tag" title="show questions tagged &#39;c++&#39;" rel="tag">c++</a> rules,I specialized my focus on <code>std::regex</code>, creating two console apps: 1.<code>renrem</code> and 2.<code>bfind</code>.<br>
  And I decided to create some convenient functions to deal with <code>regex</code> in <a href="/questions/tagged/c%2b%2b" class="post-tag" title="show questions tagged &#39;c++&#39;" rel="tag">c++</a> as easy as possible plus all with <code>std</code>; named RFC ( = regex function collection )</p>
  
  <p>There are several strange things that always make me surprise, but this one ruined all my attempt and those two console apps.  </p>
  
  <p>One of the important functions is <code>count_match</code> that counts number of match inside a string.  Here is the full code:  </p>
  
  <pre><code>unsigned int count_match( const std::string&amp; user_string, const std::string&amp; user_pattern, const std::string&amp; flags = "o" ){
  
      const bool flags_has_i = flags.find( "i" ) &lt; flags.size();
      const bool flags_has_g = flags.find( "g" ) &lt; flags.size();
  
      std::regex::flag_type regex_flag                  = flags_has_i ? std::regex_constants::icase         : std::regex_constants::ECMAScript;
  //    std::regex_constants::match_flag_type search_flag = flags_has_g ? std::regex_constants::match_default : std::regex_constants::format_first_only;
      std::regex rx( user_pattern, regex_flag );
      std::match_results&lt; std::string::const_iterator &gt; mr;
  
      unsigned int counter = 0;
      std::string temp = user_string;
      while( std::regex_search( temp, mr, rx ) ){
          temp = mr.suffix().str();
          ++counter;
      }
  
      if( flags_has_g ){
          return counter;
      } else {
          if( counter &gt;= 1 ) return 1;
          else               return 0;
      }
  
  }  
  </code></pre>
  
  <p>First of all, as you can see, the line for <code>search_flag</code> was commented because it is ignored by <code>std::regex_search</code> and <strong>I do not know why?</strong> since -- the exact flag is accepted for <code>std::regex_repalce</code>. So <code>std::regex_search</code> ignores the <code>format_first_only</code> but <code>std::regex_replace</code> accepts it. Let's it goes.  </p>
  
  <p>The main problem is here that the <code>icase</code> flag is also ignored when the pattern is <strong>character class</strong> -> <code>[]</code>. In fact when the pattern is only <code>capital letter</code> or <code>small letter</code>: <code>[A-Z]</code> or <code>[a-z]</code>  </p>
  
  <p>Supposing this string s = <code>"ONE TWO THREE four five six seven"</code>  </p>
  
  <p>the output for <a href="/questions/tagged/c%2b%2b" class="post-tag" title="show questions tagged &#39;c++&#39;" rel="tag">c++</a> <code>std</code>  </p>
  
  <pre><code>std::cout &lt;&lt; count_match( s, "[A-Z]+" ) &lt;&lt; '\n';          // 1 =&gt; First match
  std::cout &lt;&lt; count_match( s, "[A-Z]+", "g" ) &lt;&lt; '\n';     // 3 =&gt; Global match
  std::cout &lt;&lt; count_match( s, "[A-Z]+", "gi" ) &lt;&lt; '\n';    // 3 =&gt; Global match plus insensitive  
  </code></pre>
  
  <p>whereas for the exact <a href="/questions/tagged/perl" class="post-tag" title="show questions tagged &#39;perl&#39;" rel="tag">perl</a> and <a href="/questions/tagged/d" class="post-tag" title="show questions tagged &#39;d&#39;" rel="tag">d</a> laugauge and <a href="/questions/tagged/c%2b%2b" class="post-tag" title="show questions tagged &#39;c++&#39;" rel="tag">c++</a> with <code>boost</code> the output is:  </p>
  
  <pre><code>std::cout &lt;&lt; count_match( s, "[A-Z]+" ) &lt;&lt; '\n';          // 1 =&gt; First match
  std::cout &lt;&lt; count_match( s, "[A-Z]+", "g" ) &lt;&lt; '\n';     // 3 =&gt; Global match
  std::cout &lt;&lt; count_match( s, "[A-Z]+", "gi" ) &lt;&lt; '\n';    // 7 =&gt; Global match plus insensitive  
  </code></pre>
  
  <hr>
  
  <p>I know about regex flavors <strong>PCRE</strong>; or <strong>ECMAScript 262</strong> that c++ uses it, But I have no ides <strong>why a simple flag, is ignored for the only search function that c++ has?</strong>  Since <code>std::regex_iterator</code> and <code>std::regex_token_iterator</code> are also use this function internally.  </p>
  
  <p>And shortly, I can not use those two my apps and RFC with <code>std</code> library because if this! </p>
  
  <p>So if someone knows according to which rule it is maybe a valid rude in <code>ECMAScript 262</code> or perhaps if I am wrong anywhere please tell me.  Thanks.</p>
  
  <hr>
  
  <p><em>tested with</em>  </p>
  
  <pre><code>gcc version 6.3.0 20170519 (Ubuntu/Linaro 6.3.0-18ubuntu2~16.04)
  clang version 3.8.0-2ubuntu4  
  </code></pre>
  
  <p><a href="/questions/tagged/perl" class="post-tag" title="show questions tagged &#39;perl&#39;" rel="tag">perl</a> code:  </p>
  
  <pre><code>perl -le '++$c while $ARGV[0] =~ m/[A-Z]+/g; print $c ;' "ONE TWO THREE four five six seven" // 3
  perl -le '++$c while $ARGV[0] =~ m/[A-Z]+/gi; print $c ;' "ONE TWO THREE four five six seven" // 7  
  </code></pre>
  
  <p><a href="/questions/tagged/d" class="post-tag" title="show questions tagged &#39;d&#39;" rel="tag">d</a> code:  </p>
  
  <pre><code>uint count_match( ref const (char[]) user_string, const (char[]) user_pattern, const (char[]) flags ){
  
      const bool flag_has_g = flags.indexOf( "g" ) != -1;
  
      Regex!( char ) rx = regex( user_pattern, flags );
      uint counter = 0;
      foreach( mr; matchAll( user_string, rx ) ){
          ++counter;
      }
  
      if( flag_has_g ){
          return counter;
      } else {
          if( counter &gt;= 1 ) return 1;
          else               return 0;
      }
  } 
  </code></pre>
  
  <p>the output:  </p>
  
  <pre><code>writeln( count_match( s, "[A-Z]+", "g" ) );  // 3
  writeln( count_match( s, "[A-Z]+", "gi" ) ); // 7  
  </code></pre>
  
  <p><a href="/questions/tagged/js" class="post-tag" title="show questions tagged &#39;js&#39;" rel="tag">js</a> code:  </p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>var s = "ONE TWO THREE four five six seven";
  
  var rx1 = new RegExp( "[A-Z]+" , "g" );
  var rx2 = new RegExp( "[A-Z]+" , "gi" );
  
  var counter = 0;
  while( rx1.exec( s ) ){
     ++counter;
  }
  document.write( counter + "&lt;br&gt;" ); // 3
  
  counter = 0;
  while( rx2.exec( s ) ){
     ++counter;
  }
  document.write( counter ); // 7</code></pre>
  </div>
  </div>
  </p>
  
  <hr>
  
  <p>Okay. After testing with <code>gcc 7.1.0</code> it turned out that with version below <code>6.3.0</code> the output is: <code>1 3 3</code> and but with <code>7.1.0</code> the output is <code>1 3 7</code>
  <a href="https://wandbox.org/permlink/5RZpHZJGJfB1FHnE" rel="nofollow noreferrer">here is the link</a>.  </p>
  
  <p>Also with this version of <code>clang</code> the output is correct. <a href="http://rextester.com/OEWX18211" rel="nofollow noreferrer">Here is the link</a>. thanks to <strong>igor-tandetnik</strong> user</p>