Boost C++ Libraries: Ticket #12797: Invalid regex recursion behavior https://svn.boost.org/trac10/ticket/12797 <p> I have found an unexpected behavior regarding recursion in regexes (in Perl mode). I've reduced the issue to the following test pattern: </p> <pre class="wiki">(?(DEFINE) (?&lt;prefix&gt;) (?&lt;dummy&gt;x) ) (?&amp;prefix) unused | (?&amp;prefix) match </pre><p> If you try to match this against <code>foo match bar</code>, the <code>match</code> word should be found. This works in both Perl and PCRE, see the <a class="ext-link" href="https://regex101.com/r/emKagD/1"><span class="icon">​</span>regex101 demo here</a>. </p> <ul><li>Removing or commenting out the <code>dummy</code> group causes the pattern to match </li><li>Making the <code>dummy</code> group empty causes the pattern to match </li><li>Replacing <code>(?&amp;prefix)</code> with <code>(?&amp;prefix)?</code> causes <code>Encountered an infinite recursion.</code> </li><li>Replacing <code>(?&amp;prefix)</code> with <code>(?&amp;prefix)?</code> but making the definition of <code>pattern</code> non-empty causes the pattern to match </li></ul><p> Here's the full test program: </p> <div class="wiki-code"><div class="code"><pre><span class="cp">#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;boost/regex.hpp&gt;</span><span class="cp"></span> <span class="k">static</span> <span class="kt">void</span> <span class="nf">test</span><span class="p">()</span> <span class="p">{</span> <span class="n">boost</span><span class="o">::</span><span class="n">regex</span> <span class="n">re</span><span class="p">(</span><span class="sa">R</span><span class="s">&quot;</span><span class="dl">regex(</span><span class="s"></span> <span class="s"> (?(DEFINE)</span> <span class="s"> (?&lt;prefix&gt;)</span> <span class="s"> (?&lt;dummy&gt;x)</span> <span class="s"> )</span> <span class="s"> (?&amp;prefix) unused | (?&amp;prefix) match</span> <span class="s"> </span><span class="dl">)regex</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">regex</span><span class="o">::</span><span class="n">perl</span> <span class="o">|</span> <span class="n">boost</span><span class="o">::</span><span class="n">regex</span><span class="o">::</span><span class="n">no_mod_s</span> <span class="o">|</span> <span class="n">boost</span><span class="o">::</span><span class="n">regex</span><span class="o">::</span><span class="n">mod_x</span> <span class="o">|</span> <span class="n">boost</span><span class="o">::</span><span class="n">regex</span><span class="o">::</span><span class="n">optimize</span><span class="p">);</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">subject</span><span class="p">(</span><span class="s">&quot;foo match bar&quot;</span><span class="p">);</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">boost</span><span class="o">::</span><span class="n">regex_replace</span><span class="p">(</span><span class="n">subject</span><span class="p">,</span> <span class="n">re</span><span class="p">,</span> <span class="s">&quot;[$&amp;]&quot;</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">format_all</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">**</span><span class="n">argv</span><span class="p">)</span> <span class="p">{</span> <span class="k">try</span> <span class="p">{</span> <span class="n">test</span><span class="p">();</span> <span class="p">}</span> <span class="k">catch</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">exception</span> <span class="n">ex</span><span class="p">)</span> <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">cerr</span> <span class="o">&lt;&lt;</span> <span class="n">ex</span><span class="p">.</span><span class="n">what</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> </pre></div></div><ul><li>Actual output is <code>foo match bar</code> </li><li>Expected output is <code>foo [match] bar</code> </li></ul><p> Tested with Boost 1.63.0 on MSVC 2015. The full pattern where the issue appeared can be found <a class="ext-link" href="http://stackoverflow.com/a/41910370/3764814"><span class="icon">​</span>here</a>. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/12797 Trac 1.4.3