<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[FAQ: Regex "Backtracking Control Verbs"]]></title><description><![CDATA[<pre><code class="language-diff">+                  BACKTRACKING CONTROL verbs
-                          FIRST post
</code></pre>
<p dir="auto">Hi, <strong>All</strong>,</p>
<p dir="auto">Since Notepad++ <strong><code>v7.7</code></strong>, its regex engine uses a new <strong>Boost</strong> regex library. First, I advice you to to see <a href="https://community.notepad-plus-plus.org/post/54345">here</a> , which discusses of various <strong><code>Boost</code></strong> <strong>version</strong> numbers.</p>
<p dir="auto">Related to our present <strong>regex engine</strong> status, these versions are :</p>
<ul>
<li>
<p dir="auto">The general <strong>Boost C++</strong> libraries version number : <strong><code>-1.64.0</code></strong></p>
</li>
<li>
<p dir="auto">The <strong>Boost-Regex</strong> library version number : <strong><code>-5.1.3</code></strong></p>
</li>
<li>
<p dir="auto">The <strong>Boost-Regex</strong> <em>documentation</em> version number : <strong><code>1.70.0</code></strong></p>
</li>
</ul>
<hr />
<p dir="auto">Our <strong>Boost</strong> regex engine uses the <strong><code>PCRE</code></strong> ( <strong>Perl Compatible Regular Expression</strong> syntax ) and, since the old <strong><code>1.55.0</code></strong> documentation, the <strong>new</strong> <strong><code>1.70.0</code></strong> regex documentation, contains only a <strong>significant</strong> difference, relative to a <strong>new</strong> feature, named <strong><code>Backtracking Control Verbs</code></strong>. Refer to the official <strong>Boost</strong> documentation, below :</p>
<p dir="auto"><a href="https://www.boost.org/doc/libs/1_70_0/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html#boost_regex.syntax.perl_syntax.backtracking_control_verbs" rel="nofollow ugc">https://www.boost.org/doc/libs/1_70_0/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html#boost_regex.syntax.perl_syntax.backtracking_control_verbs</a></p>
<p dir="auto">Note that on <a href="https://www.rexegg.com/backtracking-control-verbs.html" rel="nofollow ugc">Rexegg</a> site, it is said :</p>
<blockquote>
<p dir="auto">The <strong>slow</strong> speed of adoption of the <strong>backtracking control verbs</strong> reflects some simple truths: they are <strong>rarely</strong> used, likely because they are <strong>poorly</strong> known and little understood by a <strong>considerable</strong> proportion of those <strong>few</strong> who have heard of them.</p>
</blockquote>
<blockquote>
<p dir="auto">Frankly, this <strong>lack</strong> of awareness is not an issue because there is <strong>so much</strong> basic material that most people, who only <strong>occasionally</strong> use regex, need to <strong>master</strong> before the features offered by <strong>backtracking verbs</strong> become <strong>meaningful</strong> !</p>
</blockquote>
<p dir="auto">I would add that the use of the <strong>backtracking control</strong> verbs are really significant in <strong>rare</strong> occasions only ! However, I’ll try to give you an oversight of these new <strong>assertions</strong> and some <strong>examples</strong> to describe them as well as some <strong>practical</strong> uses, found out from general documentation and from some of my <strong>tests</strong> !</p>
<hr />
<p dir="auto">But, before studying these <strong>backtracking control</strong> Verbs, let’s say a word about the <strong>backtracking</strong> process itself !</p>
<ul>
<li>
<p dir="auto">If we consider the simple regex <strong><code>\w+\w{3}\d+</code></strong>, against the string <strong>ABC12345DEFABC56667892</strong>, the main steps are :</p>
<ul>
<li>
<p dir="auto">First, the <strong><code>\w+</code></strong> pattern matches, from the starting position <strong><code>1</code></strong>, <strong>all</strong> the string <strong>ABC12345DEFABC56667892</strong></p>
</li>
<li>
<p dir="auto">Then, the <strong><code>\w+</code></strong> <strong>backtracks</strong> ( so decreases by <strong><code>3</code></strong> the <strong>current</strong> value of quantifier <strong><code>+</code></strong>), in order that the <strong><code>\w+</code></strong> pattern matches the string <strong>ABC12345DEFABC56667</strong> and  that the <strong><code>\w{3}</code></strong> pattern matches the string <strong>892</strong></p>
</li>
<li>
<p dir="auto">Finally, the <strong><code>\w+\w{3}</code></strong>  backtracks ( so decrease by <strong><code>1</code></strong> the current value of quantifier <strong><code>+</code></strong>, in <strong><code>\w+</code></strong> pattern ), in order that the <strong><code>\w+</code></strong> pattern matches <strong>ABC12345DEFABC5666</strong> , the <strong><code>\w{3}</code></strong> pattern matches the string <strong>789</strong>  and the <strong><code>\d+</code></strong> pattern matches the digit <strong>2</strong></p>
</li>
</ul>
</li>
</ul>
<p dir="auto">In this specific regex, only the first <strong><code>+</code></strong> quantifier of <strong><code>\w+</code></strong> was involved in the <strong>backtracking</strong> process. The <strong><code>+</code></strong> quantifier of <strong><code>\d+</code></strong> was <strong>not</strong> concerned at all as <strong>nothing</strong> follows the pattern <strong><code>\d+</code></strong></p>
<p dir="auto"><strong>Remark</strong> : It is <strong>important</strong> to note that the <strong>backtracking</strong> process is not related, exactly, to <strong>backward</strong> directions, but, rather, to the idea that the regex engine <strong>recalculates</strong> an other <strong>possible</strong> match, from <strong>current</strong> starting position, in the string !</p>
<ul>
<li>
<p dir="auto">Let’s consider the regex <strong><code>(?-i)\w+?C\d{6}</code></strong>, against the <strong>same</strong> string <strong>ABC12345DEFABC56667892</strong></p>
<ul>
<li>
<p dir="auto">First, the regex <strong><code>\w+?</code></strong>, with the <strong>lazy</strong> quantifier beginning at <strong><code>1</code></strong>, matches the letter <strong>A</strong>. But as the other letter is not a <strong>C</strong>, it <strong>backtracks</strong> and, from position <strong><code>1</code></strong> in string, increases the quantifier to <strong><code>2</code></strong> to get the string <strong>AB</strong> and, this time, the <strong><code>C</code></strong> pattern does match the next <strong>C</strong> letter</p>
</li>
<li>
<p dir="auto">Then the <strong><code>\d{6}</code></strong> pattern tries to find <strong>six</strong> digits. However, after the five digits <strong>12345</strong>, the <strong>D</strong> letter cannot be matched by the <strong><code>\d</code></strong> pattern. Thus, the regex engine <strong>backtracks</strong> to starting position <strong><code>1</code></strong> and increase the common value <strong><code>2</code></strong> of the <strong><code>+?</code></strong> quantifier, by <strong>one</strong>, …till value <strong><code>13</code></strong>, in order that the <strong>next</strong> char is, again, a letter <strong>C</strong></p>
</li>
<li>
<p dir="auto">Finally the <strong><code>\d{6}</code></strong> pattern looks for <strong>six consecutive</strong> digits and does find a match with the string <strong>566678</strong>. So, the search process <strong>stops</strong> with pattern <strong><code>\w+?</code></strong> = <strong>ABC12345DEFAB</strong>, pattern <strong><code>C</code></strong>  = <strong>C</strong> and pattern <strong><code>\d{6}</code></strong> = <strong>566678</strong></p>
</li>
</ul>
</li>
</ul>
<hr />
<p dir="auto">To begin with, let’s say that the <strong>backtracking control</strong> verbs can be described as <strong>zero-width</strong> assertions, absolutely <strong>invisible</strong> when the regex engine looks <strong>forward</strong>, in <strong>current</strong> regex pattern. <strong>Six</strong> different verbs are managed by the <strong><code>Boost</code></strong> regex engine</p>
<p dir="auto">As mentioned in the <a href="https://www.rexegg.com/backtracking-control-verbs.html#accept" rel="nofollow ugc">Rexegg</a> site, the <strong>two</strong> verbs <strong><code>(*ACCEPT)</code></strong> and <strong><code>(*FAIL)</code></strong> should <strong>not</strong> be strictly designed as <strong>backtracking control</strong> Verbs. Indeed :</p>
<ul>
<li>
<p dir="auto">The <strong><code>(*ACCEPT)</code></strong> <strong>assertion</strong> should be simply seen as a <strong><code>control</code></strong> Verb</p>
</li>
<li>
<p dir="auto">The <strong><code>(*FAIL)</code></strong> <strong>assertion</strong> should be called a <strong><code>backtracking</code></strong> Verb.</p>
</li>
</ul>
<p dir="auto">It is important to point out that these <strong>two</strong> verbs act <strong>as soon as</strong> they are encountered, in <strong>forward</strong> direction !</p>
<ul>
<li><strong>Four</strong> other verbs <strong><code>(*THEN)</code></strong>, <strong><code>(*PRUNE)</code></strong>, <strong><code>(*SKIP)</code></strong> and <strong><code>(*COMMIT)</code></strong> can be <strong>fully</strong> designed as <strong><code>backtracking control</code></strong> verbs, as they act <strong>only</strong> during the <strong>backtracking</strong> process and, of course, <strong>forces</strong> the regex engine to realize a <strong>specific</strong> action</li>
</ul>
<p dir="auto">However, if we consider the <strong>general</strong> pattern <strong><code>Regex_A(*VERB)Regex_B</code></strong>, note that <strong>backtracking</strong> is allowed, both, inside the <strong><code>Regex_A</code></strong> pattern and/or inside the <strong><code>Regex_B</code></strong> pattern. However, the regex engine <strong>cannot</strong> backtrack from the <strong><code>Regex_B</code></strong> part to the <strong><code>Regex_A</code></strong> part, crossing <strong>backward</strong> the <strong><code>(*VERB)</code></strong> assertion !</p>
<ul>
<li>
<p dir="auto">For instance, the regex <strong><code>\w+\d+(*PRUNE).+\d</code></strong>, against the string <strong>AAAA123456789BBBB----YYYY0ZZZZ</strong>, matches the part <strong>AAAA123456789BBBB----YYYY0</strong> ( Refer to the <strong><code>PRUNE</code></strong> <strong>backtracking control</strong> verb, further on ! )</p>
<ul>
<li>
<p dir="auto">The <strong><code>regex_A</code></strong> ( <strong><code>\w+\d+</code></strong> ) backtracks from <strong>last</strong> B letter to digit <strong>8</strong>, in order to match the <strong>AAAA123456789</strong> part</p>
</li>
<li>
<p dir="auto">The <strong><code>regex_B</code></strong> ( <strong><code>.+\d</code></strong> ) backtracks from <strong>last</strong> Z to <strong>last</strong> Y, in order to match the <strong>BBBB----YYYY0</strong> part</p>
</li>
</ul>
</li>
<li>
<p dir="auto">As <strong>no</strong> additional <strong>backtracking</strong> process is needed, an <strong>overall</strong> match occurs</p>
</li>
<li>
<p dir="auto">Now, this <strong>same</strong> regex, against the string <strong>AAAA123456789BBBB----YYYYZZZZ</strong> ( with <strong><code>0</code></strong> digit <strong>missing</strong> ) would <strong>not</strong> match anything :</p>
<ul>
<li>
<p dir="auto">First, the <strong><code>regex_A</code></strong> ( <strong><code>\w+\d+</code></strong> ), as before, would match the string <strong>AAAAA123456789</strong></p>
</li>
<li>
<p dir="auto">However, the <strong><code>Regex_B</code></strong> ( <strong><code>.+\d</code></strong> ) cannot obviously match the remainder <strong>BBB----YYYYZZZZ</strong></p>
</li>
<li>
<p dir="auto">Even after <strong>backtracking</strong> to the first <strong>B</strong> letter, no match can be found, because <strong>no more</strong> digit occurs. So, the regex engine would need to backtrack onto the <strong><code>Regex_A</code></strong> pattern till <strong>before</strong> the <strong>8</strong> digit, in order that <strong><code>.+</code></strong> would match the <strong>8</strong> digit and <strong><code>\d</code></strong> would match the <strong>9</strong> digit</p>
</li>
<li>
<p dir="auto">Because of the <strong><code>(*PRUNE)</code></strong> verb, this behavior is <strong>not</strong> allowed and the match attempt <strong>fails</strong> at <strong>current</strong> position, Then, the regex engine advances to <strong>next</strong> position, in string, but no match occurs at <strong>any</strong> subsequent position, too !</p>
</li>
</ul>
</li>
</ul>
<p dir="auto">Just see the difference with the simple regex <strong><code>\w+\d+.+\d</code></strong>, against the string <strong>AAAA123456789BBBB----YYYYZZZZ</strong>. This time, the substring <strong>AAAA123456789</strong> matches ! ( <strong><code>\w+</code></strong> = <strong>AAAA123456</strong>, <strong><code>\d+</code></strong> = <strong>7</strong>, <strong><code>.+</code></strong> = <strong>8</strong> and <strong><code>\d</code></strong> = <strong>9</strong> )</p>
<hr />
<ul>
<li>
<p dir="auto">When the regex engine moves <strong>forward</strong>, in the pattern, these <strong>four</strong> verbs have absolutely <strong>no</strong> influence and they <strong>always</strong> match. So their <strong>special</strong> semantics are <strong>never</strong> activated !</p>
</li>
<li>
<p dir="auto">When the regex engine moves <strong>downward</strong>, because <strong>backtracking</strong> is needed, it’s <strong>not</strong> allowed to <strong>cross</strong> them. In other words, the regex engine can <strong>never</strong> go back to the <strong>left</strong> of these <strong>backtracking control</strong> verbs !</p>
</li>
</ul>
<p dir="auto">Finally, the <strong><code>(*MARK)</code></strong> verb is <strong>not</strong> supported by the present <strong><code>Boost</code></strong> library, implemented in Notepad++, <strong>whatever</strong> its version</p>
<hr />
<p dir="auto">We’ll begin to study the <strong><code>4</code></strong> true <strong>backtracking control</strong> verbs according to this <strong>order</strong> : <strong><code>(*COMMIT)</code></strong>, <strong><code>(*SKIP)</code></strong>, <strong><code>(*PRUNE)</code></strong> and <strong><code>(*THEN)</code></strong>. Next, it should be easier, for anyone, to figure out the <strong>relations</strong> and <strong>differences</strong> between each of them :-)</p>
<p dir="auto">Then, we’ll study the <strong>two remaining</strong> verbs <strong><code>(*ACCEPT)</code></strong> and <strong><code>(*FAIL)</code></strong>. The later is <strong>often</strong> used in conjunction with other <strong>backtracking control</strong> verbs to perform <strong>enhanced</strong> behaviors</p>
<p dir="auto">This rather <strong>long</strong> documentation must be divided into <strong>five</strong> posts !</p>
<hr />
<h3>_______________ <strong><code>(*COMMIT)</code></strong> _______________</h3>
<p dir="auto"><code> </code></p>
<p dir="auto">In <strong><code>BOOST</code></strong> documentation, it is said :</p>
<blockquote>
<p dir="auto"><strong><code>(*COMMIT)</code></strong> Has no effect unless backtracked onto, in which case <strong>all subsequent</strong> matching/searching attempts are <strong>abandoned</strong>.</p>
</blockquote>
<p dir="auto">This means that, if at <strong>current</strong> position in string, the <strong>regex</strong> engine can match the part <strong>before</strong> <strong><code>(*COMMIT)</code></strong> but <strong>cannot</strong> match the part <strong>after</strong> <strong><code>(*COMMIT)</code></strong>, as any <strong>backtracking</strong> is <strong>canceled</strong> to the <strong>left</strong> of <strong><code>(*COMMIT)</code></strong>, the regex engine <strong>discards</strong> any further search and the <strong>current</strong> match attempt just <strong>fails</strong>. So, the regex engine simply abandons any <strong>further</strong> match attempt, the <strong>overall</strong> match just <strong>fails</strong> and the search process <strong>stops</strong></p>
<p dir="auto">Note that <strong>after</strong> the general <strong>failure</strong>, the <strong>current</strong> starting position remains <strong>right after</strong> the <strong>last successful</strong> attempt</p>
<p dir="auto">In other words, the <strong>general</strong> regex <strong><code>regex_A(*COMMIT)regex_B</code></strong> means that if <strong><code>regex_A</code></strong> have already matched, then <strong><code>regex_B</code></strong> <strong>must</strong> necessarily match too, <strong>right after</strong>. If  <strong>not</strong>, the <strong>overall</strong> match <strong>fails</strong> !</p>
<p dir="auto">On <a href="https://www.rexegg.com/backtracking-control-verbs.html#commit" rel="nofollow ugc">Rexegg site</a> it is said :</p>
<blockquote>
<p dir="auto">“You can read the <strong><code>(*COMMIT)</code></strong> token as <strong>past</strong> this point, we are <strong>committed</strong> to finding a match, in <strong>this</strong> match attempt, or <strong>none</strong> at all”.</p>
</blockquote>
<p dir="auto">So, for instance, the regex <strong><code>(*COMMIT)ABC</code></strong> means that if the string <strong>ABC</strong> is <strong>not</strong> found, at <strong>caret</strong> location, the search process simply <strong>stops</strong> !</p>
<hr />
<p dir="auto">Consider the regex <strong><code>(?-i)AB+(*COMMIT)CD|\w{2}.|AB+(*COMMIT)CH</code></strong>, against the text <strong>---ABBZE---ABBBBCH---ABBBCY---ABBBBCD---</strong></p>
<p dir="auto">—ABBZE—ABBBBCH—ABBBCY—ABBBBCD—</p>
<p dir="auto">So, according to the effect of a <strong><code>(*COMMIT)</code></strong> <strong>backtracking control</strong> verb, let’s follow the regex engine’s work :</p>
<ul>
<li>
<p dir="auto">The <strong>first <code>3</code></strong> positions of the string ( <strong><code>\-\-\-</code></strong> ) are skipped, as <strong>no</strong> alternative can match a <strong>dash</strong> character</p>
</li>
<li>
<p dir="auto">So, the <strong>starting</strong> position is right <strong>before</strong> the string <strong>ABBZE</strong> :</p>
<ul>
<li>
<p dir="auto">The <strong>first</strong> found pattern <strong><code>AB+(*COMMIT)CD</code></strong> matches <strong>ABB</strong> but cannot match <strong>CD</strong></p>
</li>
<li>
<p dir="auto">So, it tries to <strong>backtrack</strong> at <strong>left</strong> of the <strong><code>(*COMMIT)</code></strong> syntax to test other values of <strong><code>AB+</code></strong></p>
</li>
<li>
<p dir="auto">Because of the <strong><code>(*COMMIT)</code></strong> control verb, this behavior is <strong>forbidden</strong> So, all which is matched, so far ( <strong><code>ABB</code></strong> ), is <strong>discarded</strong> and the regex engine abandons any <strong>further</strong> match attempt, too. So the <strong>overall</strong> match <strong>fails</strong>.</p>
</li>
<li>
<p dir="auto">However, note that the <strong>starting</strong> position remains at the <strong>very beginning</strong> of the scanned string, so right <strong>before</strong> the string <strong>---ABBZE</strong></p>
</li>
</ul>
</li>
</ul>
<hr />
<p dir="auto">The regex <strong><code>1(?=2(*COMMIT)3)</code></strong> finds a <strong><code>1</code></strong> digit <em>IF</em> followed with <strong>23</strong>, but <strong>all</strong> the search process <strong>stops</strong> completely as soon as a <strong><code>1</code></strong> digit is followed by a <strong><code>2</code></strong> and any char <strong>different</strong> from <strong><code>3</code></strong>. Note that, after this failure, the <strong>current</strong> starting point remains <strong>after</strong> the <strong>last successful</strong> attempt ! ( the digit <strong><code>1</code></strong> which is followed with the string <strong>23</strong> )</p>
<p dir="auto">Whereas the regex <strong><code>1(?=23)</code></strong> find a <strong><code>1</code></strong> digit <em>IF</em> followed with <strong>23</strong> and search process goes on, to <strong>next</strong> positions, in string, to search for <strong>other successful</strong> match attempts as, for instance, the third value <strong><code>123</code></strong> !</p>
<p dir="auto">Test these <strong>two</strong> regexes <strong><code>1(?=2(*COMMIT)3)</code></strong> and <strong><code>1(?=23)</code></strong>, against the text, below :</p>
<pre><code class="language-z">10
11
123  OK
14
18
19
123  OK
12
123  KO
127
</code></pre>
<hr />
<p dir="auto"><strong>Third</strong> example : the regex <strong><code>(a(*COMMIT)b)+ac</code></strong>  can be re-written <strong><code>(a(*COMMIT)ba(*COMMIT)ba.....a(*COMMIT)b)ac</code></strong> <strong>fails</strong> against the text <strong>abac</strong>, because in the <strong>second</strong> repeat, <strong><code>a(*COMMIT)b</code></strong> <strong>fails</strong> to match <strong>ac</strong> and, as <strong>backtracking</strong> is <strong>not</strong> allowed in order to choose only <strong>one</strong> repeat, followed with <strong>ac</strong>, the <strong>overall</strong> match <strong>fails</strong> due to the verb <strong><code>(*COMMIT)</code></strong></p>
<hr />
<p dir="auto">It’s worth to point out that the <strong><code>(*COMMIT)</code></strong> verb does not <strong>always</strong> commit. It’s the case when an other <strong>backtracking control</strong> verb is located at <strong>right</strong> at the <strong><code>(*COMMIT)</code></strong> verb :</p>
<p dir="auto">For instance, the regex <strong><code>(?-i)AB+(*COMMIT)(*SKIP)CD|\w{2}.</code></strong>, against the string <strong>---ABBZE---</strong> does match the string <strong>ZE-</strong>, because the <strong><code>(*SKIP)</code></strong> verb if found, <strong>first</strong>, <strong>before</strong> reaching, <strong>backwards</strong>, the <strong><code>(*COMMIT)</code></strong> verb. In contrast, with the almost <strong>similar</strong> regex <strong><code>(?-i)AB+(*COMMIT)B(*SKIP)CD|\w{2}.</code></strong>, the regex engine would need to backtrack at left of the <strong><code>(*COMMIT)</code></strong> verb =&gt; Immediate <strong>failure</strong> !</p>
<hr />
<p dir="auto">I found a <strong>practical</strong> use of the <strong><code>(*COMMIT)</code></strong> verb :</p>
<p dir="auto">We all know, that <strong>if</strong> the <strong><code>Wrap around</code></strong> option is <strong>not</strong> used, the process is run from <strong>current</strong> location till the <strong>very end</strong> of file(s). Now, imagine that you would like to execute an S/R from current position till the <strong>very beginning</strong> of file. The <strong>backward</strong> option is usually <strong>not enabled</strong> when regex search is  involved and, anyway, some regexes do not behave properly, in <strong>backward</strong> direction !</p>
<p dir="auto">So, add a simple character, <strong>not</strong> used yet, <strong>alone</strong> in a line, anywhere in your <strong>current</strong> file. I chose the <strong><code>#</code></strong> character but, of course, any <strong>other</strong> char may be chosen !</p>
<p dir="auto">Now, see the behavior of the regex <strong><code>#(*COMMIT)\w+|\w+</code></strong></p>
<ul>
<li>
<p dir="auto">As long as the <strong><code>#</code></strong> character is not found, at <strong>current</strong> starting position, the <strong>second</strong> alternative of the regex is used and matches any <strong>word</strong> ( <strong><code>\w+</code></strong> )</p>
</li>
<li>
<p dir="auto">As soon as the <strong><code>#</code></strong> character is found, at <strong>current</strong> starting position, the regex engine tries to find some <strong>word</strong> chars, right after the <strong><code>#</code></strong> symbol. This is impossible as it is followed with a <strong>line-break</strong> ! So, due to the <strong><code>(*COMMIT)</code></strong> verb, the overall regex <strong>fails</strong> and the process stops !</p>
</li>
</ul>
<p dir="auto">So, if we consider the <strong>shorter</strong> search regex <strong><code>(#(*COMMIT)|)\w+</code></strong> and the replacement regex <strong><code>\U$0</code></strong> with the <strong><code>Wrap around</code></strong> option <strong>ticked</strong>, this S/R would change any word in <strong>uppercase</strong> but the <strong>replacement</strong> process would <strong>stop</strong> soon as a <strong><code>#</code></strong> symbol, <strong>not immediately</strong> followed by a <strong>word</strong> char, is found, further on, in <strong>current</strong> text !</p>
]]></description><link>https://community.notepad-plus-plus.org/topic/19632/faq-regex-backtracking-control-verbs</link><generator>RSS for Node</generator><lastBuildDate>Sat, 05 Sep 2026 15:02:12 GMT</lastBuildDate><atom:link href="https://community.notepad-plus-plus.org/topic/19632.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 01 Jul 2020 07:44:14 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to FAQ: Regex "Backtracking Control Verbs" on Thu, 09 Nov 2023 14:15:49 GMT]]></title><description><![CDATA[<p dir="auto"><a href="https://community.notepad-plus-plus.org/post/55641">https://community.notepad-plus-plus.org/post/55641</a></p>
<p dir="auto">Hello, <strong>All</strong>,</p>
<p dir="auto">During my study of the <strong>backtracking control</strong> verbs ( see posts above ), I noticed this article which described ways to <strong>pre-define</strong> some <strong>subroutines</strong>, which can be used to build numerous <strong>modular</strong> patterns, at the <strong>same</strong> time :</p>
<p dir="auto"><a href="https://www.rexegg.com/regex-tricks.html#pseudo-define" rel="nofollow ugc">https://www.rexegg.com/regex-tricks.html#pseudo-define</a></p>
<p dir="auto">Note that the special <strong>conditional</strong> <strong><code>(?(DEFINE).....)</code></strong> structure was created, originally, to this purpose, by <strong>modern</strong> regex engines, including our <strong><code>Boost</code></strong> regex engine ! I already <strong>discussed</strong> of this syntax in this post below :</p>
<p dir="auto"><a href="https://community.notepad-plus-plus.org/post/52608">https://community.notepad-plus-plus.org/post/52608</a></p>
<p dir="auto">So, for instance, with the <strong>free-spacing</strong> mode, the regex below :</p>
<pre><code class="language-z">(?x-i)
(?(DEFINE)      #  START of the conditional DEFINE structure
([A-Z]{2}\d)    #    TWO CAPITAL letters, followed with a DIGIT in Group 1
)               #  END of the conditional DEFINE structure
(?1)-(?1)-(?1)  #  THREE "Group 1" triplets, separated with DASHES
</code></pre>
<p dir="auto">Against the string <strong>YH5-RC6-UY0-BD5-AZ3-KL9</strong>, would match the <strong>two</strong> substrings <strong>YH5-RC6-UY0</strong> and <strong>BD5-AZ3-KL9</strong></p>
<hr />
<p dir="auto">Now, in <strong>Rexegg</strong> site, we are told that, instead of the <strong><code>(?(DEFINE).....)</code></strong> <strong>conditional</strong> structure, we can use the <strong><code>(*FAIL)</code></strong> <strong>backtracking control</strong> verb to get a <strong>similar</strong> behavior, according to the syntax below, using an <strong>optional non-capturing</strong> group :</p>
<pre><code class="language-z">(?x-i)
(?:             # START of an OPTIONAL NON-CAPTURING group
([A-Z]{2}\d)    #   TWO CAPITAL letters, followed with a DIGIT in Group 1
(*F)            #   Backtracking Control verb (*FAIL)
)?              # END of the OPTIONAL NON-CAPTURING group
(?1)-(?1)-(?1)  # THREE "Group 1" triplets, separated with DASHES
</code></pre>
<p dir="auto">Remark that, instead of the <strong><code>(*F)</code></strong> verb, we may also use the <strong>negative look-ahead</strong> <strong><code>(?!)</code></strong> syntax for <strong>identical</strong> results</p>
<hr />
<p dir="auto">Now, I’ve found out a <strong>more simple</strong> syntax :</p>
<pre><code class="language-z">(?x-i)
([A-Z]{2}\d)    #  TWO CAPITAL letters, followed with a DIGIT in Group 1
(*F)            #  Backtracking Control verb (*FAIL)
|               #    OR
(?1)-(?1)-(?1)  #  THREE "Group 1" triplets, separated with DASHES
</code></pre>
<p dir="auto">How this <strong>regex</strong> syntax works, against the string <strong>YH5-RC6-UY0-BD5-AZ3-KL9</strong> ?</p>
<ul>
<li>
<p dir="auto">First, the regex engine tries to match the part <strong><code>([A-Z]{2}\d)</code></strong> and, indeed, matches the substring <strong>HY5</strong>.</p>
</li>
<li>
<p dir="auto">At the same time, it <strong>stores</strong> the pattern <strong><code>[A-Z]{2}\d</code></strong> in <strong>group <code>1</code></strong></p>
</li>
<li>
<p dir="auto">Then the regex engine meets the <strong>backtracking control</strong> verb <strong><code>(*F)</code></strong> which forces it to <strong>backtrack</strong></p>
</li>
<li>
<p dir="auto">So the current match <strong>HY5</strong> is <strong>discarded</strong> and the <strong>starting</strong> position remains right <strong>before</strong> the <strong>first</strong> letter <strong>Y</strong></p>
</li>
<li>
<p dir="auto">Then the regex engine tries the <strong>other</strong> alternative <strong><code>?1)-(?1)-(?1)</code></strong> and matches, successively, the <strong>two</strong> substrings <strong>YH5-RC6-UY0</strong> and <strong>BD5-AZ3-KL9</strong>, as we expect to !</p>
</li>
</ul>
<hr />
<p dir="auto">Note the effect of the <strong><code>(*FAIL)</code></strong> verb is exactly the <strong>same</strong> as if the regex engine would try to match a <strong>specific</strong> pattern that does <strong>not</strong> exist in subject string ! So, let simply <strong>substitute</strong> this verb with, for instance, the <strong>CURRENY</strong> sign <strong><code>¤</code></strong>, of Unicode code point <strong>``\x{00a4}`</strong>. which is generally <strong>not</strong> used in files !</p>
<p dir="auto">You can use the Windows <strong>input method</strong>, hitting the <strong><code>Alt</code></strong> key and typing number <strong><code>0164</code></strong> on the <strong>numeric</strong> keypad</p>
<p dir="auto">So we get the regex :</p>
<pre><code class="language-z">(?x-i)
([A-Z]{2}\d)    #  TWO CAPITAL letters, followed with a DIGIT in Group 1
¤               #  The CURRENCY sign character ( In fact, any NON-EXISTENT character, in CURRENT file ! )
|               #    OR
(?1)-(?1)-(?1)  #  THREE "Group 1" triplets, separated with DASHES
</code></pre>
<p dir="auto">Why <strong>my</strong> syntax also works :</p>
<ul>
<li>
<p dir="auto">First, the regex engine tries to match the part <strong><code>([A-Z]{2}\d)</code></strong> and, indeed, matches the substring <strong>HY5</strong>.</p>
</li>
<li>
<p dir="auto">At the same time, it <strong>stores</strong> the pattern <strong><code>[A-Z]{2}\d</code></strong> in <strong>group <code>1</code></strong></p>
</li>
<li>
<p dir="auto">But it <strong>cannot</strong> match the following <strong>currency</strong> sign <strong><code>¤</code></strong> and the regex engine naturally <strong>backtracks</strong></p>
</li>
<li>
<p dir="auto">The <strong>starting</strong> position remains right <strong>before</strong> the <strong>first</strong> letter <strong>Y</strong></p>
</li>
<li>
<p dir="auto">And the regex engine tries the <strong>other</strong> alternative <strong><code>?1)-(?1)-(?1)</code></strong>, which matches, successively, the <strong>two</strong> substrings <strong>YH5-RC6-UY0</strong> and <strong>BD5-AZ3-KL9</strong></p>
</li>
</ul>
<p dir="auto">Note that the regex engine does <strong>remember</strong> of the pattern contained in <strong>group <code>1</code></strong> because, despite of the <strong>backtracking</strong> phase, the search process still goes on !</p>
<p dir="auto">Of course, instead of the <strong>single</strong> character <strong><code>¤</code></strong>, you can, either, choose a simple <strong>string</strong>, which does <strong>not</strong> exist in <strong>current</strong> file. For instance, <strong><code>///</code></strong> or <strong><code>@@</code></strong> or <strong><code>_X_</code></strong></p>
<p dir="auto">It’s also <strong>important</strong> to point out that you can perfectly use <strong>named</strong> group(s), for <strong>all</strong> these syntaxes. For instance, my <strong>last</strong> regex syntax can be rewritten :</p>
<pre><code class="language-z">(?x-i)
(?&lt;Seq&gt;[A-Z]{2}\d)       #  TWO CAPITAL letters, followed with a DIGIT in NAMED group 'Seq'
¤                        #  The CURRENCY sign character ( In fact, any NON-EXISTENT character, in CURRENT file ! )
|                        #    OR
(?&amp;Seq)-(?&amp;Seq)-(?&amp;Seq)  #  THREE 'Seq' triplets, separated with DASHES
</code></pre>
<hr />
<p dir="auto">Of course, <strong>all</strong> the syntaxes, above, which help us to create a <strong>library</strong> of <strong>pre-defined</strong> groups are mostly <strong>valuable</strong>, when you try to search between <strong>numerous</strong> patterns, built up from these <strong>elementary</strong> patterns !</p>
<p dir="auto">To that purpose, let’s expose a more <strong>interesting</strong> and <strong>practical</strong> example, regarding the search of <strong>specific</strong> sequences within the <strong>genetic code</strong> !</p>
<p dir="auto">If necessary, refer for a very <strong>basic</strong> background, about <strong>genetic</strong> code, at the <strong>end</strong> of this post !</p>
<p dir="auto">From now on, the <strong>genetic</strong> notions invoked are <strong>only</strong> the fruit of my <strong>imagination</strong> and are, in <strong>no</strong> way, based on <strong>scientific</strong> data. !! It’s just used to <strong>demonstrate</strong> the <strong>interest</strong> of the above <strong>regex</strong> syntaxes</p>
<p dir="auto">Let’s suppose that the <strong><code>3</code></strong> <strong>genetic</strong> sequences <strong><code>CGUUUA</code></strong>, <strong><code>GCCACUAAACAG</code></strong> and <strong><code>AAUCGACAU</code></strong>, named <strong>Seq_1</strong>, <strong>Seq_2</strong> and <strong>Seq_3</strong>, are of <strong>main</strong> importance in order to build up <strong>greater</strong> genetic <strong>chains</strong> from a <strong>combination</strong> of these <strong>components</strong></p>
<p dir="auto">Now, let’s assume that we want, at the <strong>same</strong> time, search for the <strong>seven</strong> combinations :</p>
<ul>
<li><strong>Seq_2</strong> + <strong>Seq_3</strong></li>
<li><strong>Seq_1</strong> + <strong>Seq_2</strong></li>
<li><strong>Seq_1</strong> + <strong>Seq_3</strong></li>
<li><strong>Seq_2</strong> + <strong>AAA</strong> codon + <strong>Seq_3</strong></li>
<li><strong>Seq_2</strong> + <strong>CCC</strong> codon + <strong>Seq_1</strong></li>
<li><strong><code>4</code></strong> consecutive <strong>Seq_1</strong> + <strong>Seq_2</strong></li>
<li><strong><code>4</code></strong> consecutive <strong>Seq_1</strong> + <strong>Seq_3</strong></li>
</ul>
<p dir="auto">Then, the regex to search <strong>any</strong> of these sequences, delimited with a <strong>start</strong> and a <strong>stop</strong> codon, could be, in <strong>free-spacing</strong> mode :</p>
<pre><code class="language-z">(?x-i)                     #  FREE-SPACING mode and NON-INSENSITIVE search

(?&lt;Seq_1&gt;CGUUUA)           #  Seq_1 definition  (  6 bases )
(?&lt;Seq_2&gt;GCCACUAAACAG)     #  Seq_2 definition  ( 12 bases )
(?&lt;Seq_3&gt;AAUCGACAU)        #  Seq_3 definition  (  9 bases )
X |                        #  An INEXISTANT character in RNA sequence      OR

(AUG|GUG|UUG)              #  Possible START codons
(?&lt;Codon&gt;[ACGU]{3})*?      #  Any number of CODONS, even ZERO, in the NAMED group Codon
\K                         #  ANYTHING matched, so far, is DISCARDED

(?:                        #  Start of a NON-CAPTURING group

(?&amp;Seq_2)(?&amp;Seq_3)      |  #    Chain 1 :  Seq_2 + Seq_3                   OR
(?&amp;Seq_1)(?&amp;Seq_2)      |  #    Chain 2 :  Seq_1 + Seq_2                   OR
(?&amp;Seq_1)(?&amp;Seq_3)      |  #    Chain 3 :  Seq_1 + Seq_3                   OR
(?&amp;Seq_2)AAA(?&amp;Seq_3)   |  #    Chain 4 :  Seq_2 + AAA + Seq_3             OR
(?&amp;Seq_3)CCC(?&amp;Seq_1)   |  #    Chain 5 :  Seq_3 + CCC + Seq_1             OR
(?&amp;Seq_1){4}(?&amp;Seq_2)   |  #    Chain 6 :  FOUR consecutive Seq_1 + Seq_2  OR
(?&amp;Seq_1){4}(?&amp;Seq_3)      #    Chain 7 :  FOUR consecutive Seq_1 + Seq_3

)                          #  END of the NON-CAPTURING group

(?=                        #  START of a LOOK-AHEAD
(?&amp;Codon)*                 #    Any number of CODONS, even ZERO
(UAA|UGA|UAG)              #    Possible STOP codons
)                          #  END of the LOOK-AHEAD

You can test this regex against these lines, below, which **all** begin with a **start** codon and end with a **stop** codon :

~~~diff
AUGUGCAACGAUCGUUUAAAUCGACAUGCCACUAAACAGUUACAUCAUACUGCCAACCAGGGCCAUGUUUAA  # Chain  3

GUGAACCAGGGCCAUGUUCGUUUAAAUCGACAUAAUCGACAUAACCCCUUACUUGCUAAUUUCUGA        # Chain  3

UUGCGUUUAAACCUAAAAGAUGGGGUCGCCACUAAACAGAAUCGACAUAAUCGACAUGGACCGUAG        # Chain  1

UUGACUUUACAUCAUACUGCCGCCACUAAACAGAAAAAUCGACAUCCCCGUUUAAAACCUUGGAGCCCGUAG  # Chains 4 then 5

AUGCGUUUACGUUUACGUUUACGUUUAGCCACUAAACAGUCAACUGGAGGAUCCCGGCAUUUUUAA        # Chains 6 then 2

GUGUCGAACUGGGGAGCGCCACCUCAUAGUUGUCGUUUACGUUUACGUUUACGUUUAAAUCGACAUUGA     # Chains 7 then 3
</code></pre>
<hr />
<p dir="auto">However, if we change the <strong>greedy</strong> quantifier, of the <strong>Codon</strong> group, with a <strong>lazy</strong> quantifier, we get <strong>other</strong> matches. This is <strong>expected</strong> because some areas <strong>overlap</strong> with other areas or <strong>include</strong> some others !</p>
<p dir="auto">So, in order to <strong>correctly</strong> detect <strong>all</strong> these chains of <strong>nucleotides</strong>, we could look, <strong>only</strong> for the <strong>zero</strong>-length location, of the <strong>start</strong> of each <strong>sequence</strong>, with the appropriate regex, below :</p>
<pre><code class="language-z">(?x-i)                     #  FREE-SPACING mode and NON-INSENSITIVE search
(?&lt;Seq_1&gt;CGUUUA)           #  Seq_1 definition (  6 bases )
(?&lt;Seq_2&gt;GCCACUAAACAG)     #  Seq_2 definition ( 12 bases )
(?&lt;Seq_3&gt;AAUCGACAU)        #  Seq_3 definition (  9 bases )
X|                         #  An INEXISTANT character in RNA sequence     OR
(?=                        #  START of a LOOK-AHEAD
(?&amp;Seq_2)(?&amp;Seq_3)      |  #    Case 1 :  Seq_2 + Seq_3                   OR
(?&amp;Seq_1)(?&amp;Seq_2)      |  #    Case 2 :  Seq_1 + Seq_2                   OR
(?&amp;Seq_1)(?&amp;Seq_3)      |  #    Case 3 :  Seq_1 + Seq_3                   OR
(?&amp;Seq_2)AAA(?&amp;Seq_3)   |  #    Case 4 :  Seq_2 + AAA + Seq_3             OR
(?&amp;Seq_3)CCC(?&amp;Seq_1)   |  #    Case 5 :  Seq_3 + CCC + Seq_1             OR
(?&amp;Seq_1){4}(?&amp;Seq_2)   |  #    Case 6 :  FOUR consecutive Seq_1 + Seq_2  OR
(?&amp;Seq_1){4}(?&amp;Seq_3)      #    Case 7 :  FOUR consecutive Seq_1 + Seq_3
)                          #  END of the LOOK-AHEAD
</code></pre>
<p dir="auto">See below, with the indication of the <strong>start</strong> of each <strong>sequence</strong> :</p>
<pre><code class="language-diff">            v
AUGUGCAACGAUCGUUUAAAUCGACAUGCCACUAAACAGUUACAUCAUACUGCCAACCAGGGCCAUGUUUAA  # Chain  3
                  v
GUGAACCAGGGCCAUGUUCGUUUAAAUCGACAUAAUCGACAUAACCCCUUACUUGCUAAUUUCUGA        # Chain  3
                           v
UUGCGUUUAAACCUAAAAGAUGGGGUCGCCACUAAACAGAAUCGACAUAAUCGACAUGGACCGUAG        # Chain  1
                     v              v
UUGACUUUACAUCAUACUGCCGCCACUAAACAGAAAAAUCGACAUCCCCGUUUAAAACCUUGGAGCCCGUAG  # Chains 4 then 5
   v                 v
AUGCGUUUACGUUUACGUUUACGUUUAGCCACUAAACAGUCAACUGGAGGAUCCCGGCAUUUUUAA        # Chains 6 then 2
                                 v                 v
GUGUCGAACUGGGGAGCGCCACCUCAUAGUUGUCGUUUACGUUUACGUUUACGUUUAAAUCGACAUUGA     # Chains 7 then 3
</code></pre>
<hr />
<p dir="auto">Now, if we want to <strong>completely</strong> match each <strong>composite</strong> sequence, we’ll use this <strong>last</strong> regex :</p>
<pre><code class="language-z">(?x-i)                     #  FREE-SPACING mode and NON-INSENSITIVE search
(?&lt;Seq_1&gt;CGUUUA)           #  Seq_1 definition (  6 bases )
(?&lt;Seq_2&gt;GCCACUAAACAG)     #  Seq_2 definition ( 12 bases )
(?&lt;Seq_3&gt;AAUCGACAU)        #  Seq_3 definition (  9 bases )
X|                         #  An INEXISTANT character in RNA sequence     OR
(?:                        #  START of a NON-CAPTURING group
(?&amp;Seq_2)(?&amp;Seq_3)      |  #    Case 1 :  Seq_2 + Seq_3                   OR
(?&amp;Seq_1)(?&amp;Seq_2)      |  #    Case 2 :  Seq_1 + Seq_2                   OR
(?&amp;Seq_1)(?&amp;Seq_3)      |  #    Case 3 :  Seq_1 + Seq_3                   OR
(?&amp;Seq_2)AAA(?&amp;Seq_3)   |  #    Case 4 :  Seq_2 + AAA + Seq_3             OR
(?&amp;Seq_3)CCC(?&amp;Seq_1)   |  #    Case 5 :  Seq_3 + CCC + Seq_1             OR
(?&amp;Seq_1){4}(?&amp;Seq_2)   |  #    Case 6 :  FOUR consecutive Seq_1 + Seq_2  OR
(?&amp;Seq_1){4}(?&amp;Seq_3)      #    Case 7 :  FOUR consecutive Seq_1 + Seq_3
)                          #  END of a NON-CAPTURING group
</code></pre>
<p dir="auto">See, below, the indication of each <strong>sequence</strong> with the <strong><code>v</code></strong> letter or the <strong><code>^</code></strong> symbol :</p>
<pre><code class="language-diff">            vvvvvvvvvvvvvvv
AUGUGCAACGAUCGUUUAAAUCGACAUGCCACUAAACAGUUACAUCAUACUGCCAACCAGGGCCAUGUUUAA   # Chain 3

                  vvvvvvvvvvvvvvv
GUGAACCAGGGCCAUGUUCGUUUAAAUCGACAUAAUCGACAUAACCCCUUACUUGCUAAUUUCUGA         # Chain 3

                           vvvvvvvvvvvvvvvvvvvvv
UUGCGUUUAAACCUAAAAGAUGGGGUCGCCACUAAACAGAAUCGACAUAAUCGACAUGGACCGUAG         # Chain 1


                     vvvvvvvvvvvvvvvvvvvvvvvv                              # Chain 4
UUGACUUUACAUCAUACUGCCGCCACUAAACAGAAAAAUCGACAUCCCCGUUUAAAACCUUGGAGCCCGUAG
                                    ^^^^^^^^^^^^^^^^^^                     # Chain 5


   vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv                                    # Chain 6
AUGCGUUUACGUUUACGUUUACGUUUAGCCACUAAACAGUCAACUGGAGGAUCCCGGCAUUUUUAA
                     ^^^^^^^^^^^^^^^^^^                                    # Chain 2


                                 vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv         # Chain 7
GUGUCGAACUGGGGAGCGCCACCUCAUAGUUGUCGUUUACGUUUACGUUUACGUUUAAAUCGACAUUGA
                                                   ^^^^^^^^^^^^^^^         # Chain 3
</code></pre>
<p dir="auto">Note that, in order to get, <strong>successively</strong>, all the occurrences, even in case of <strong>overlapping</strong>, hit the <strong><code>F3</code></strong> shortcut to get a <strong>match</strong>. Then, hit the <strong><code>Left</code></strong> arrow, followed by the <strong><code>Right</code></strong> arrow, to advance of <strong>one</strong> position in text !</p>
<hr />
<p dir="auto">At last, I would say that it’s obvious that I’m <strong>not</strong> competing, with my <strong>simple</strong> regexes, against all the powerful <strong>ORF finding</strong> tools used by biologists ;-)) Refer to :</p>
<p dir="auto"><a href="https://en.wikipedia.org/wiki/Open_reading_frame#ORF_finding_tools" rel="nofollow ugc">https://en.wikipedia.org/wiki/Open_reading_frame#ORF_finding_tools</a></p>
<p dir="auto">Best Regards,</p>
<p dir="auto">guy038</p>
<p dir="auto">Here is a <strong>very basic</strong> summary, about <strong>genetic</strong> code, for the <strong>sole</strong> purpose of that <strong>present</strong> discussion :</p>
<blockquote>
<p dir="auto"><strong><code>DNA</code></strong> is a <strong>double ordered helix</strong> chain, made of four <strong>nucleotides</strong>, associated by <strong>pairs</strong>, <strong>adenine</strong> ( <strong><code>A</code></strong> ) with  <strong>thymine</strong> ( <strong><code>T</code></strong> )  and  <strong>guanine</strong> ( <strong><code>G</code></strong> ) with  <strong>cytosine</strong> ( <strong><code>C</code></strong> ), which carries all the <strong>genetic</strong> instructions for development, functioning, growth and reproduction of <strong>all</strong> known <strong>living</strong> organisms</p>
<p dir="auto">A <strong><code>gene</code></strong> is a <strong>sequence</strong> of <strong>nucleotides</strong> that encodes, either, the <strong>synthesis</strong> of the <strong><code>RNA</code></strong> molecule from the <strong><code>DNA</code></strong> molecule or the <strong>synthesis</strong> of a <strong>protein</strong> from a <strong><code>RNA</code></strong> molecule and may contain more than <strong><code>1,000</code></strong> pairs of <strong>nucleotides</strong>. Humans have nearly <strong><code>20,000</code></strong> genes, whose about <strong><code>2,000</code></strong> are thought <strong>essential</strong> to our survival !</p>
<p dir="auto">Each <strong>triplet</strong> of nucleotides, named <strong>codon</strong>, part of a <strong>double</strong>-stranded <strong><code>DNA</code></strong> or part of a <strong>single</strong>-stranded <strong><code>RNA</code></strong> molecule, corresponds to an <strong>amino-acid</strong>, during the <strong>transcription</strong> process to <strong><code>RNA</code></strong> or during the <strong>translation</strong> process to a <strong>protein</strong></p>
<p dir="auto">A single <strong>translated</strong> region of the <strong>genetic</strong> code, in the <strong><code>DNA</code></strong> molecule, is called an <strong><code>ORF</code></strong> ( <strong>Open reading Frame</strong> ), containing, generally, a <strong>minimum</strong> of <strong><code>100</code></strong> to <strong><code>150</code></strong> <strong>codons</strong></p>
<p dir="auto">After the <strong>transcription</strong> phase, from the <strong><code>DNA</code></strong> molecule into <strong><code>Pre-mRNA</code></strong> and the <strong>suppression</strong> of <strong>introns</strong>, we get the <strong>mature</strong> <strong><code>RNA</code></strong> molecule, made of four <strong>nucleotides</strong>, associated by <strong>pairs</strong>, too : <strong>adenine</strong> ( <strong><code>A</code></strong> )  with <strong>uracil</strong> ( <strong><code>U</code></strong> ) and <strong>guanine</strong> ( <strong><code>G</code></strong> ) with <strong>cytosine</strong> ( <strong><code>C</code></strong> )</p>
<p dir="auto">In <strong><code>RNA</code></strong>, the <strong><code>ORF</code></strong> zone has become the <strong><code>Protein Coding Region</code></strong>, composed of :</p>
<ul>
<li>A <strong>start</strong> codon  <strong><code>[ AUG , GUG , UUG ]</code></strong></li>
<li>A <strong>continuous</strong> stretch of <strong>codons</strong></li>
<li>A <strong>stop</strong> codon  <strong><code>[ UAA , UGA , UAG ]</code></strong></li>
</ul>
<p dir="auto">If we consider, for instance, the <strong>genome</strong> of the <strong>Escherichia Coli</strong> bacteria <strong><code>K-12</code></strong>, the <strong>proportions</strong> of each <strong>start</strong> and <strong>stop</strong> codons are :</p>
<blockquote>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="text-align:center">START</th>
<th style="text-align:center">STOP</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">Codon</td>
<td style="text-align:center">Codon</td>
</tr>
</tbody>
<tbody>
<tr>
<td style="text-align:center"><strong><code>AUG</code></strong>    <strong>83</strong>%</td>
<td style="text-align:center"><strong><code>UAA</code></strong>    <strong>63</strong>%</td>
</tr>
<tr>
<td style="text-align:center"><strong><code>GUG</code></strong>    <strong>14</strong>%</td>
<td style="text-align:center"><strong><code>UGA</code></strong>    <strong>29</strong>%</td>
</tr>
<tr>
<td style="text-align:center"><strong><code>UUG</code></strong>     <strong>3</strong>%</td>
<td style="text-align:center"><strong><code>UAG</code></strong>     <strong>8</strong>%</td>
</tr>
</tbody>
</table>
</blockquote>
</blockquote>
<p dir="auto">Refer also to :</p>
<p dir="auto"><a href="https://en.wikipedia.org/wiki/Introduction_to_genetics" rel="nofollow ugc">https://en.wikipedia.org/wiki/Introduction_to_genetics</a></p>
<p dir="auto"><a href="https://en.wikipedia.org/wiki/DNA" rel="nofollow ugc">https://en.wikipedia.org/wiki/DNA</a></p>
<p dir="auto"><a href="https://en.wikipedia.org/wiki/RNA" rel="nofollow ugc">https://en.wikipedia.org/wiki/RNA</a></p>
<p dir="auto"><a href="https://en.wikipedia.org/wiki/Gene" rel="nofollow ugc">https://en.wikipedia.org/wiki/Gene</a></p>
<p dir="auto"><a href="https://en.wikipedia.org/wiki/Open_reading_frame" rel="nofollow ugc">https://en.wikipedia.org/wiki/Open_reading_frame</a></p>
<p dir="auto"><a href="https://en.wikipedia.org/wiki/Start_codon" rel="nofollow ugc">https://en.wikipedia.org/wiki/Start_codon</a></p>
<p dir="auto"><a href="https://en.wikipedia.org/wiki/Stop_codon" rel="nofollow ugc">https://en.wikipedia.org/wiki/Stop_codon</a></p>
]]></description><link>https://community.notepad-plus-plus.org/post/55641</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/55641</guid><dc:creator><![CDATA[guy038]]></dc:creator><pubDate>Thu, 09 Nov 2023 14:15:49 GMT</pubDate></item><item><title><![CDATA[Reply to FAQ: Regex "Backtracking Control Verbs" on Sun, 22 Oct 2023 22:01:00 GMT]]></title><description><![CDATA[<pre><code class="language-diff">+                  BACKTRACKING CONTROL verbs
-                     FIFTH and LAST post
</code></pre>
<p dir="auto">A <strong>last</strong> summary :</p>
<ul>
<li>
<p dir="auto">The <strong>zero</strong>-width <strong><code>(*THEN)</code></strong>, <strong><code>(*PRUNE)</code></strong>, <strong><code>(*SKIP)</code></strong> and <strong><code>(*COMMIT)</code></strong> <strong>backtracking control</strong> verbs always <strong>match</strong> in <strong>forward</strong> direction but and always <strong>fail</strong>, on <strong>backtracking</strong>, when the <strong><code>(*......)</code></strong> verb is crossed in <strong>backward</strong> direction</p>
</li>
<li>
<p dir="auto">The <strong>zero</strong>-width <strong><code>(*ACCEPT)</code></strong> <strong>backtracking control</strong> verb always <strong>matches</strong> the <strong>current</strong> match attempt, till the <strong><code>(*ACCEPT)</code></strong> verb, in <strong>forward</strong> direction</p>
</li>
</ul>
<p dir="auto">–The <strong>zero</strong>-width <strong><code>(*FAIL)</code></strong> / <strong><code>(*F)</code></strong> <strong>backtracking control</strong> verb always <strong>fails</strong> the <strong>current</strong> match attempt, in <strong>forward</strong> direction. So, it <strong>always</strong> backtracks in order to test <strong>other</strong> parts of the <strong>overall</strong> regex, if any</p>
<p dir="auto">And, if we consider the <strong>general</strong> syntax  <strong><code>Regex_A(*......)RegexB</code></strong>, the <strong>next</strong> starting position, of the <strong>regex</strong> engine, in string, is :</p>
<ul>
<li>
<p dir="auto">When the verb <strong><code>(*......) </code></strong> is found in <strong>forward</strong> direction :</p>
<ul>
<li>
<p dir="auto">For <strong><code>(*THEN)</code></strong> :   Right <strong>after</strong> the characters <strong>matched</strong> by the <strong>overall</strong> pattern <strong><code>Regex_A(*THEN)Regex_B</code></strong></p>
</li>
<li>
<p dir="auto">For <strong><code>(*PRUNE)</code></strong> :  Right <strong>after</strong> the characters <strong>matched</strong> by the <strong>overall</strong> pattern <strong><code>Regex_A(*PRUNE)Regex_B</code></strong></p>
</li>
<li>
<p dir="auto">For <strong><code>(*SKIP)</code></strong> :   Right <strong>after</strong> the characters <strong>matched</strong> by the <strong>overall</strong> pattern <strong><code>Regex_A(*SKIP)Regex_B</code></strong></p>
</li>
<li>
<p dir="auto">For <strong><code>(*COMMIT)</code></strong> : Right <strong>after</strong> the characters <strong>matched</strong> by the <strong>overall</strong> pattern <strong><code>Regex_A(*COMMIT)Regex_B</code></strong></p>
</li>
<li>
<p dir="auto">For <strong><code>(*ACCEPT)</code></strong> : Right <strong>after</strong> the characters <strong>matched</strong> by the <strong><code>Regex_A</code></strong> pattern part</p>
</li>
<li>
<p dir="auto">For <strong><code>(*FAIL)</code></strong> :   <strong>Unchanged</strong>, so the location <strong>before</strong> running the <strong>overall</strong> pattern <strong><code>Regex_A(*FAIL)Regex_B</code></strong></p>
</li>
</ul>
</li>
<li>
<p dir="auto">When the verb <strong><code>(*......) </code></strong> is found in <strong>backward</strong> direction, because of <strong>backtracking</strong> :</p>
<ul>
<li>
<p dir="auto">For <strong><code>(*THEN)</code></strong> :   The <strong>current</strong> location when running the <strong>overall</strong> pattern <strong><code>Regex_A(*THEN)Regex_B</code></strong></p>
</li>
<li>
<p dir="auto">For <strong><code>(*PRUNE)</code></strong> :  The location <strong>next</strong> to the <strong>current</strong> location when running the <strong>overall</strong> pattern <strong><code>Regex_A(*PRUNE)Regex_B</code></strong></p>
</li>
<li>
<p dir="auto">For <strong><code>(*SKIP)</code></strong> :   Right <strong>after</strong> the characters <strong>matched</strong> by the <strong><code>Regex_A</code></strong> pattern part</p>
</li>
<li>
<p dir="auto">For <strong><code>(*COMMIT)</code></strong> : <strong>Unchanged</strong>, so the location <strong>before</strong> running the <strong>overall</strong> pattern <strong><code>Regex_A(*COMMIT)Regex_B</code></strong></p>
</li>
</ul>
</li>
</ul>
<hr />
<p dir="auto">To <strong>conclude</strong> this study of the <strong>backtracking control</strong> verbs, here is a <strong>last</strong> example which <strong>recapitulates</strong> the different <strong>backtracking control</strong> verbs and some of their <strong>combinations</strong>. All the regexes, in the <strong>table</strong>, below, are tested against the <strong>same</strong> subject string :</p>
<p dir="auto"><strong>aaaa1bbbcccccc#</strong></p>
<pre><code class="language-z">•-----------------------------•----------------------------------------•-------------------------------------------------------•---------------------------------•
|     REGULAR Expression      |            Different MATCHES           |   SECOND regex alternative STATUS, after FIRST try    | Caret AFTER 1st try of 2ND Alt. |
•-----------------------------•----------------------------------------•-------------------------------------------------------•---------------------------------•
|  c+|a+\d|b+|#               |  aaaa1   bbb   cccccc   #              |  MATCH, in FORWARD direction                          |  Right AFTER  the 1 DIGIT       |
|  c+|\w+\d|b+|#              |  aaaa1   bbb   cccccc   #              |  MATCH, AFTER backtracking from LAST c to 1           |  Right AFTER  the 1 DIGIT       |
|                             |                                        |                                                       |                                 |
|  c+|a++\d|b+|#              |  aaaa1   bbb   cccccc   #              |  MATCH, in FORWARD direction                          |  Right AFTER  the 1 DIGIT       |
|  c+|\w++\d|b+|#             |          bbb   cccccc   #              |  NO match, as backtracking  is NOT allowed            |  Right BEFORE the FIRST a       |
|                             |                                        |                                                       |                                 |
|                             |                                        |                                                       |                                 |
|  c+|a+(*FAIL)\d|b+|#        |          bbb   cccccc   #              |  Match FAILURE, though MATCH in FORWARD direction     |  Right BEFORE the FIRST a       |
|  c+|\w+(*FAIL)\d|b+|#       |          bbb   cccccc   #              |  Match FAILURE, though MATCH after BACKTRACKING       |  Right BEFORE the FIRST a       |
|                             |                                        |                                                       |                                 |
|                             |                                        |                                                       |                                 |
|  c+|a+(*SKIP)\d|b+|#        |  aaaa1   bbb   cccccc   #              |  MATCH, in FORWARD direction                          |  Right AFTER  the 1 DIGIT       |
|  c+|\w+(*SKIP)\d|b+|#       |  #  ( + cccccc IF caret AFTER LAST b ) |  NO match, as BACTRACKING is NOT allowed              |  Right BEFORE the # symbol      |
|                             |                                        |                                                       |                                 |
|  c+|a+(*SKIP)(*F)\d|b+|#    |          bbb   cccccc   #              |  Match FAILURE, though MATCH in FORWARD direction     |  Right BEFORE the 1 DIGIT       |
|  c+|\w+(*SKIP)(*F)\d|b+|#   |  #  ( + cccccc IF caret AFTER LAST b ) |  Match FAILURE and NO match as NO backtracking        |  Right BEFORE the # symbol      |
|                             |                                        |                                                       |                                 |
|                             |                                        |                                                       |                                 |
|  c+|a+(*PRUNE)\d|b+|#       |  aaaa1   bbb   cccccc   #              |  MATCH, in FORWARD direction                          |  Right AFTER  the 1 DIGIT       |
|  c+|\w+(*PRUNE)\d|b+|#      |                cccccc   #              |  Alternative DISCARDED + NO match as NO backtracking  |  Right AFTER  the FIRST a       |
|                             |                                        |                                                       |                                 |
|  c+|a+(*PRUNE)(*F)\d|b+|#   |          bbb   cccccc   #              |  Match FAILURE, though MATCH in FORWARD direction     |  Right AFTER  the FIRST a       |
|  c+|\w+(*PRUNE)(*F)\d|b+|#  |                cccccc   #              |  Match FAILURE and NO match as NO backtracking        |  Right AFTER  the FIRST a       |
|                             |                                        |                                                       |                                 |
|                             |                                        |                                                       |                                 |
|  c+|a+(*COMMIT)\d|b+|#      |  aaaa    bbb   cccccc   #              |  MATCH, in FORWARD direction                          |  Right AFTER  the 1 DIGIT       |
|  c+|\w+(*COMMIT)\d|b+|#     |  cccccc   #  ( IF caret AFTER LAST b ) |  CANCELS any SUBSEQUENT attempt as NO backtracking    |  Right BEFORE the FIRST a       |
|                             |                                        |                                                       |                                 |
|  c+|a+(*ACCEPT)\d|b+|#      |  aaaa    bbb   cccccc   #              |  MATCH of part BEFORE (*ACCEPT), in FORWARD direction |  Right BEFORE the 1 DIGIT       |
|  c+|\w+(*ACCEPT)\d|b+|#     |  aaaa1bbbcccccc         #              |  MATCH of part BEFORE (*ACCEPT), in FORWARD direction |  Right BEFORE the # symbol      |
|                             |                                        |                                                       |                                 |
|  c+|a+(*THEN)\d|b+|#        |  aaaa1   bbb   cccccc   #              |  MATCH, in FORWARD direction                          |  Right AFTER  the 1 DIGIT       |
|  c+|\w+(*THEN)\d|b+|#       |                cccccc   #              |  NO match, as BACTRACKING is NOT allowed              |  Right BEFORE the FIRST a       |
•-----------------------------•----------------------------------------•-------------------------------------------------------•---------------------------------•
</code></pre>
<hr />
<p dir="auto">For <strong>additional</strong> information, refer to :</p>
<p dir="auto"><a href="https://www.boost.org/doc/libs/1_70_0/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html#boost_regex.syntax.perl_syntax.backtracking_control_verbs" rel="nofollow ugc">https://www.boost.org/doc/libs/1_70_0/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html#boost_regex.syntax.perl_syntax.backtracking_control_verbs</a></p>
<p dir="auto"><a href="https://www.rexegg.com/backtracking-control-verbs.html" rel="nofollow ugc">https://www.rexegg.com/backtracking-control-verbs.html</a></p>
<p dir="auto"><a href="https://www.rexegg.com/backtracking-control-verbs.html#skipfail" rel="nofollow ugc">https://www.rexegg.com/backtracking-control-verbs.html#skipfail</a></p>
<p dir="auto"><a href="https://www.pcre.org/current/doc/html/pcre2pattern.html#SEC29" rel="nofollow ugc">https://www.pcre.org/current/doc/html/pcre2pattern.html#SEC29</a></p>
<p dir="auto"><a href="https://perl.developpez.com/documentations/en/5.20.1/perlre.html#Special-Backtracking-Control-Verbs" rel="nofollow ugc">https://perl.developpez.com/documentations/en/5.20.1/perlre.html#Special-Backtracking-Control-Verbs</a></p>
<p dir="auto">and this article on <strong>stackoverflow</strong> :</p>
<p dir="auto"><a href="https://stackoverflow.com/questions/19992984/verbs-that-act-after-backtracking-and-failure" rel="nofollow ugc">https://stackoverflow.com/questions/19992984/verbs-that-act-after-backtracking-and-failure</a></p>
<hr />
<p dir="auto">Now, it’s up to you ! Just <strong>experiment</strong> all these <strong>backtracking control</strong> verbs and try to find out some <strong>practical</strong> uses of them ;-))</p>
<p dir="auto">Best regards,</p>
<p dir="auto">guy038</p>
]]></description><link>https://community.notepad-plus-plus.org/post/55468</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/55468</guid><dc:creator><![CDATA[guy038]]></dc:creator><pubDate>Sun, 22 Oct 2023 22:01:00 GMT</pubDate></item><item><title><![CDATA[Reply to FAQ: Regex "Backtracking Control Verbs" on Thu, 09 Nov 2023 14:24:21 GMT]]></title><description><![CDATA[<pre><code class="language-diff">+                  BACKTRACKING CONTROL verbs
-                 FOURTH post ( continuation )
</code></pre>
<h3>_______________ <strong><code>(*FAIL)</code></strong> _______________</h3>
<p dir="auto"><code> </code></p>
<p dir="auto">In <strong><code>BOOST</code></strong> documentation, it is said :</p>
<blockquote>
<p dir="auto"><strong><code>(*FAIL)</code></strong> Causes the match to fail <strong>unconditionally</strong> at this point, can be used to <strong>force</strong> the engine to <strong>backtrack</strong></p>
</blockquote>
<p dir="auto">This means that, if at <strong>current</strong> position in string, the <strong>active</strong> part of the pattern meets a <strong>zero-width</strong> <strong><code>(*FAIL)</code></strong> verb, then the <strong>current</strong> match attempt is <strong>always</strong> considered as <strong>unsuccessful</strong>. So the regex engine, necessarily, <strong>backtracks</strong> in order to find out <strong>other</strong> patterns, in the <strong>overall</strong> regex, to make a match attempt <strong>successful</strong>, at <strong>current</strong> location in string</p>
<p dir="auto">Because of the <strong>inconditional</strong> failure of the <strong>current</strong> match attempt, due to <strong><code>(*FAIL)</code></strong>, the <strong>current</strong> starting position has <strong>not</strong> changed. For instance, the regex <strong><code>AABBCC(*FAIL)|.+</code></strong>, against the string <strong>AABBCCABDEF---GGAC</strong>, will match <strong>all</strong> string contents, from the start location <strong><code>1</code></strong>, even if the string <strong>AABBCC</strong> has been matched before the <strong><code>(*FAIL)</code></strong> verb was <strong>encountered</strong> !</p>
<p dir="auto">Note that the <strong><code>(*FAIL)</code></strong> syntax can be <strong>abbreviated</strong> as <strong><code>(*F)</code></strong> and may also be replaced by a <strong>negative</strong> look-ahead of an <strong>empty</strong> string <strong><code>(?!)</code></strong>, which is an <strong>always false</strong> assertion because <strong>any</strong> character is, necessarily, followed with an <strong>empty</strong> string. You could use, also, a regex like <strong><code>(?=A)B</code></strong> which is, obviously, an <strong>always</strong> false assertion, too !</p>
<p dir="auto">One example : the regex  <strong><code>A((A|Z)(*FAIL)|B|C)D</code></strong> is just equivalent to the regex <strong><code>A(B|C)D</code></strong>, as the <strong>alternative</strong> <strong><code>(A|Z)(*FAIL)</code></strong> always <strong>fails</strong> ! So, this regex <strong>only</strong> matches the strings <strong>ABD</strong> and <strong>ACD</strong>, against the text <strong>AZD   ABD   AAD   ACD</strong></p>
<hr />
<p dir="auto">I see <strong><code>4</code></strong> <strong>practical</strong> uses of the <strong><code>(*FAIL)</code></strong> <strong>backtracking control</strong> verb :</p>
<ol>
<li>If the <strong>overall</strong> regex contains some <strong>complicated</strong> alternatives, you can <strong>temporarily</strong> <strong>omit</strong> one of them, for testing. Simply add, <strong>after</strong> this alternative  and <strong>before</strong> the <strong><code>|</code></strong> symbol, a <strong><code>(*F)</code></strong> verb, which will <strong>always</strong> fails any match attempt of this <strong>specific</strong> alternative. For instance, with the <strong>free-spacing</strong> mode, the regex, below, would only match the strings <strong>AAAA</strong>, <strong>BBBB</strong>, <strong>DDDD</strong> and <strong>EEEE</strong></li>
</ol>
<pre><code class="language-z">(?x-i)
AAAA        |
BBBB        |
CCCC  (*F)  |
DDDD        |
EEEE
</code></pre>
<p dir="auto">Note that we could have used, also, the <strong><code>#</code></strong> <strong>comment</strong> char, placing <strong>all</strong> the pattern <strong><code>CCCC</code></strong> in <strong>comments</strong> :</p>
<pre><code class="language-z">(?x-i)
AAAA        |
BBBB        |
# CCCC      |
DDDD        |
EEEE
</code></pre>
<hr />
<ol start="2">
<li>The  <strong><code>(*FAIL)</code></strong> or <strong><code>(*F)</code></strong> syntaxes can be used to <strong>force</strong> the regex engine to <strong>backtrack</strong>, after <strong>defining</strong> some <strong>groups</strong>, not intended to be consumed at <strong>current</strong> position in string, but <strong>later</strong></li>
</ol>
<p dir="auto">For instance, let’s examine the regex <strong><code>(?-i)([A-Z])([a-z])([0-9])(*F)|(?1)(?3)(?2)|((?1)|(?2))(?3){2}</code></strong> against the string <strong>A3h  AAD  x45  Z4a   b8Q   H09   BAc  000  Y1y</strong></p>
<ul>
<li>
<p dir="auto">The <strong>first</strong> alternative is the part <strong><code>([A-Z])([a-z])([0-9])(*F)</code></strong> which <strong>defines</strong> <strong><code>3</code></strong> groups : <strong><code>[A-Z]</code></strong>, <strong><code>[a-z]</code></strong> and <strong><code>[0-9]</code></strong> standing ,respectively, for an <strong>uppercase</strong> letter, a <strong>lowercase</strong> letter and a <strong>digit</strong></p>
</li>
<li>
<p dir="auto">The <strong>second</strong> alternative <strong><code>(?1)(?3)(?2)</code></strong> represents <strong>subroutine</strong> calls to the groups ( An <strong>uppercase</strong> letter followed with a <strong>digit</strong> and a <strong>lowercase</strong> letter )</p>
</li>
<li>
<p dir="auto">The <strong>third</strong> alternative <strong><code>((?1)|(?2))(?3){2}</code></strong> represents other <strong>subroutine calls</strong> to groups ( A <strong>letter</strong> followed with <strong>two</strong> digits )</p>
</li>
</ul>
<p dir="auto">Note that it does <strong>not</strong> matter whether the <strong>first</strong> alternative is <strong>matched</strong> or <strong>not</strong>. Each time the <strong>overall</strong> regex is processed, the regex engine <strong>always</strong> tries this alternative <strong>first</strong> and, in all cases, it attempts to <strong>match</strong> the <strong>three</strong> regexes, <strong>consecutively</strong>, storing them as <strong>groups</strong> <strong><code>1</code></strong> and <strong><code>2</code></strong> and <strong><code>3</code></strong>, for <strong>further</strong> use, via the <strong>subroutine</strong> calls !</p>
<p dir="auto"><strong>Remark</strong> : The use of the <strong><code>(*FAIL)</code></strong> verb can also be <strong>emulated</strong> with the special <strong><code>(DEFINE)</code></strong> variable, in a <strong>conditional</strong> group, so the <strong><code>(?(DEFINE).....)</code></strong> syntax</p>
<p dir="auto">In our <strong>particular</strong> case, it would lead to the regex <strong><code>(?-i)(?(DEFINE)([A-Z])([a-z])([0-9]))(?1)(?3)(?2)|((?1)|(?2))(?3){2}</code></strong></p>
<p dir="auto">Now, I also found out a <strong>very simple</strong> way to <strong>emulate</strong> the <strong><code>(*FAIL)</code></strong> verb or the <strong><code>(?(DEFINE)...)</code></strong> <strong>conditional</strong> structure :</p>
<ul>
<li>Use the syntax <strong><code>(?-i)([A-Z])([a-z])([0-9])¤|(?1)(?3)(?2)|((?1)|(?2))(?3){2}</code></strong>, which substitutes the <strong><code>(*FAIL)</code></strong> verb with <strong>any</strong> char or string, <strong>not present</strong> in your text. I chose the <strong><code>¤</code></strong> character.</li>
</ul>
<p dir="auto">Indeed, although the <strong>first</strong> alternative <strong><code>([A-Z])([a-z])([0-9])¤</code></strong> will <strong>never</strong> match, the <strong>three</strong> regexes <strong><code>[A-Z]</code></strong>, <strong><code>[a-z]</code></strong> and <strong><code>[0-9]</code></strong> are, indeed, <strong>stored</strong> as <strong>groups</strong> <strong><code>1</code></strong>, <strong><code>2</code></strong> and <strong><code>3</code></strong> for <strong>further</strong> use, via the <strong>subroutine</strong> calls <strong><code>(?1)</code></strong> , <strong><code>(?2)</code></strong> and <strong><code>(?3)</code></strong> ;-))</p>
<hr />
<p dir="auto">So, these regexes, with, <strong>either</strong>, <strong><code>(*F)</code></strong> verb, the <strong><code>(DEFINE)</code></strong> assertion or the <strong>non-existent</strong> char <strong><code>¤</code></strong>, matches any <strong><code>3-CHARS</code></strong> string of <strong>non-accentuated</strong> characters :</p>
<ul>
<li>
<p dir="auto"><strong>Beginning</strong> with an <strong>upper-case</strong> letter, <strong>ending</strong> with a <strong>lower-case</strong> letter and with a <strong>digit</strong> in between</p>
</li>
<li>
<p dir="auto"><strong>Beginning</strong> with any <strong>letter</strong> and followed with <strong>two digits</strong></p>
</li>
</ul>
<pre><code class="language-z">Az1   A3h  AAD  x45  Z4a   Az1   b8Q   H09   BAc  000  Y1y
      111       222  333               444             555
</code></pre>
<hr />
<ol start="3">
<li>In <strong><code>Perl</code></strong>, the <strong><code>(*FAIL)</code></strong> verb is <strong>commonly</strong> used to get <strong>all</strong> the different branches of a <strong>match tree</strong></li>
</ol>
<p dir="auto">In the <a href="https://www.rexegg.com/backtracking-control-verbs.html#failusecases" rel="nofollow ugc">Rexegg</a> site,  it is said, for instance :</p>
<blockquote>
<ul>
<li>
<p dir="auto">This script line <strong><code>'abc' =~ /\w+(?{print "$&amp;\n";})(*F)/</code></strong> prints, <strong>successively</strong>, the strings <strong>abc</strong>,  <strong>ab</strong>, <strong>a</strong>, <strong>bc</strong>, <strong>b</strong> and <strong>c</strong></p>
</li>
<li>
<p dir="auto">First, the <strong><code>\w+</code></strong> matches the whole string <strong>abc</strong></p>
</li>
<li>
<p dir="auto">Then, the <strong>code capsule</strong> <strong>prints</strong> the match</p>
</li>
<li>
<p dir="auto">Now, the <strong><code>(*F)</code></strong> verb forces the regex engine to <strong>backtrack</strong></p>
</li>
<li>
<p dir="auto">So, the regex engine <strong>gives up</strong> the <strong><code>c</code></strong></p>
</li>
<li>
<p dir="auto">And the callback prints <strong>ab</strong></p>
</li>
<li>
<p dir="auto">Again, the <strong><code>(*F)</code></strong> verb <strong>forces</strong> the regex engine to <strong>backtrack</strong></p>
</li>
<li>
<p dir="auto">And so on !</p>
</li>
</ul>
</blockquote>
<hr />
<ol start="4">
<li>In <strong>next</strong> chapter we’ll learn about the <strong><code>(*SKIP)(*FAIL)</code></strong> construct which is a <strong>powerful</strong> way of <strong>excluding</strong> some patterns, from the match !</li>
</ol>
<hr />
<p dir="auto">A last point regarding the <strong><code>(*FAIL)</code></strong> <strong>backtracking control</strong> verb :</p>
<p dir="auto">As mentioned in <a href="https://www.rexegg.com/backtracking-control-verbs.html#failvsaccept" rel="nofollow ugc">rexegg</a>, this verb is <strong>not</strong> the opposite of the <strong><code>(*ACCEPT)</code></strong> verb. If it were the case, then the <strong><code>(*FAIL)</code></strong> would mean, at <strong>current</strong> point, in string, the match attempt just <strong>fails</strong>. In fact, the <strong>true</strong> opposite of the <strong><code>(*ACCEPT)</code></strong> verb is the combination of the <strong>two</strong> verbs <strong><code>(*PRUNE)</code></strong> and <strong><code>(*FAIL)</code></strong> or, even better, the combination of the <strong>two</strong> verbs <strong><code>(*SKIP)</code></strong> and <strong><code>(*FAIL)</code></strong> !</p>
<p dir="auto">For instance, the regex <strong><code>(?-i)([a-z]+(*ACCEPT)|\w+)[A-Z]+\d+</code></strong> against the string <strong>azrdfgsdFGSDFG12345</strong> is just <strong>equivalent</strong> to the pattern <strong><code>(?-i)([a-z]+(*ACCEPT))</code></strong> which matches the beginning <strong>azrdfgs</strong> of the string</p>
<p dir="auto">So, we’re tying to find out a <strong>verb</strong> structure which means <strong>DON’T accept</strong>, like the <strong><code>\K</code></strong> syntax, which would <strong>not</strong> take in account or, in other words, would <strong>skip</strong> the <strong><code>[a-z]+</code></strong> pattern, matched so far !</p>
<p dir="auto">If we substitute the <strong><code>(*ACCEPT)</code></strong> verb with the <strong><code>(*FAIL)</code></strong> verb, in the <strong>same</strong> pattern, so the regex <strong><code>(?-i)([a-z]+(*FAIL)|\w+)|[A-Z]+\d+</code></strong>, it matches <strong>all</strong> the subject string <strong>azrdfgsdFGSDFG12345</strong> which isn’t our expected match. Indeed, because of the <strong><code>(*FAIL)</code></strong> verb , it forces the regex engine to <strong>backtrack</strong>, at <strong>current</strong> position in string, for an <strong>other</strong> match attempt… which is <strong>successful</strong>, as the <strong>second</strong> alternative <strong><code>\w+</code></strong> graps <strong>all</strong> the subject string</p>
<p dir="auto">Now if we add the <strong><code>(*PRUNE)</code></strong> verb, before the <strong><code>(*FAIL)</code></strong> verb, we get the <strong>new</strong> regex <strong><code>(?-i)([a-z]+(*PRUNE)(*FAIL)|\w+)[A-Z]+\d+</code></strong> which does matches the <strong>remaining</strong> part of the string <strong>after</strong> the <strong>lower-case</strong> letters. Now, after meeting the <strong><code>(PRUNE)</code></strong> verb, in <strong>backward</strong> direction the match attempt <strong>fails</strong> but, this time, the regex engine moves to the <strong>next</strong> starting position <strong>before</strong> doing a <strong>new</strong> match attempt</p>
<p dir="auto">We would get the same <strong>expected</strong> result with the regex <strong><code>(?-i)([a-z]+(*SKIP)(*FAIL)|\w+)[A-Z]+\d+</code></strong>, which would, globally, <strong>skip</strong> the part matched, so far, by the pattern <strong>before</strong> the <strong><code>(*SKIP)</code></strong> verb ! The <strong>association</strong> of these <strong>two</strong> verbs is described right below.</p>
<hr />
<h3>_______________ <strong><code>(*SKIP)(*FAIL)</code></strong> _______________</h3>
<p dir="auto"><code> </code></p>
<p dir="auto">The <strong>combination</strong> <strong><code>(*SKIP)(*FAIL)</code></strong> or <strong><code>(*SKIP)(*F)</code></strong> means that everything matched on <strong>left</strong> side of <strong><code>(*SKIP)(*FAIL)</code></strong> is <strong>discarded</strong> and that the regex engine <strong>must</strong> move to the location right <strong>after</strong> this <strong>discarded</strong> match for a <strong>new</strong> match attempt !</p>
<p dir="auto">A <strong>generic</strong> regex would be : <strong>What_I_do_not_want<code>(*SKIP)(*FAIL)|</code>What_I_want</strong>    or    <strong>What_I_do_not_want<code>(*SKIP)(*F)|</code>What_I_want</strong></p>
<p dir="auto">For instance, in order to <strong>surround</strong> any word with <strong>two</strong> <strong><code>-</code></strong> characters, except whose <strong>already</strong> surrounded by <strong>curly</strong> braces, <strong><code>{}</code></strong>, use one of the <strong>regex</strong> S/R, below : :</p>
<ul>
<li>
<p dir="auto">SEARCH <strong><code>{[^}]*}(*SKIP)(*F)|\b\w+\b</code></strong>    REPLACE <strong><code>-$0-</code></strong></p>
</li>
<li>
<p dir="auto">SEARCH <strong><code>{[^}]*}(*SKIP)(?!)|\b\w+\b</code></strong>    REPLACE <strong><code>-$0-</code></strong></p>
</li>
</ul>
<p dir="auto">Test it, against the sentence : <strong>This is a test with some {text} to see {if} it works"</strong></p>
<p dir="auto"><strong>Each</strong> time a <strong><code>{xxxx}</code></strong> zone is reached, it’s <strong>skipped</strong> and the <strong>current</strong> starting position moves to the location where the <strong><code>(*F)</code></strong> verb or the <strong><code>(?!)</code></strong> syntax occur</p>
<p dir="auto">Of course, you may, simply, use the regex S/Rs below, <strong>without</strong> any <strong>control</strong> verb, for an <strong>exact</strong> replacement  :</p>
<ul>
<li>
<p dir="auto">SEARCH  <strong><code>{[^}]*}|(\b\w+\b)</code></strong>    REPLACE  <strong><code>?1-$0-:$0</code></strong></p>
</li>
<li>
<p dir="auto">SEARCH  <strong><code>({[^}]*}.*?\K)?\b\w+\b</code></strong>    REPLACE  <strong><code>-$0-</code></strong></p>
</li>
</ul>
<p dir="auto">Note the <strong>difference</strong> with this search, <strong>without</strong> the **<code>(*SKIP)</code>**part :  :</p>
<p dir="auto">SEARCH <strong><code>{[^}]*}(*F)|\b\w+\b</code></strong></p>
<p dir="auto">This time, as the <strong><code>(*SKIP)</code></strong> verb is <strong>absent</strong>, when the string <strong>{text}</strong> is reached and evaluated it <strong>backtracks</strong> because of <strong><code>(*F)</code></strong> and, as the <strong>second</strong> alternative <strong>cannot</strong> match, too, the <strong>current</strong> starting position, in string, goes <strong>next</strong> and the part <strong><code>\w+</code></strong> does match the <strong>text</strong> part</p>
<p dir="auto"><strong>Second</strong> example :</p>
<p dir="auto">Let’s consider the table, below, where the <strong>third</strong> delimiter <strong><code>|</code></strong> has been changed into the <strong><code>!</code></strong> symbol</p>
<pre><code class="language-z">| abc | def ! ghi | jkl | mno |
| abc | def ! ghi | jkl | mno |
</code></pre>
<p dir="auto">Then the <strong>regex</strong> S/R :</p>
<p dir="auto">SEARCH <strong><code>(?-s).*!(*SKIP)(*F)|\w+</code></strong></p>
<p dir="auto">REPLACE <strong><code>\U$0</code></strong></p>
<p dir="auto">would change this <strong>table</strong> as :</p>
<pre><code class="language-z">| abc | def ! GHI | JKL | MNO |
| abc | def ! GHI | JKL | MNO |
</code></pre>
<p dir="auto">But, we can use the syntax  <strong><code>(?-s)(?!.*!)\w+</code></strong>, <strong>without</strong> any <strong>backtracking control</strong> verb, too !</p>
<hr />
<p dir="auto">Before, with the <strong><code>(*COMMIT)</code></strong> verb and a <strong>dummy</strong> character, we saw a method to do an S/R <strong>only</strong> in the <strong>first</strong> part of a file.</p>
<p dir="auto">In a <strong>similar</strong> way, we can run an S/R, only in the <strong>last</strong> part of a file. Again, let’s choose the <strong><code>#</code></strong> character, inserted around the <strong>middle</strong> of current file. Then the following S/R would change all words <strong>uppercase</strong>, <strong>after</strong> the <strong><code>#</code></strong> symbol, till the <strong>very end</strong> of file</p>
<p dir="auto">SEARCH <strong><code>(?s)\A^.*#(*SKIP)(*F)|\w+</code></strong></p>
<p dir="auto">REPLACE <strong><code>\U$0</code></strong></p>
<p dir="auto">However, note that this <strong>shorter</strong> search syntax, <strong><code>(?s)\A^.*#\K|\w+</code></strong>, <strong>without</strong> any <strong>backtracking control</strong> verb, would produce the <strong>same</strong> result !</p>
<p dir="auto">So, in short, the <strong><code>(*SKIP)(*FAIL)</code></strong> construct means :</p>
<p dir="auto"><strong>Discard</strong> anything that has been <strong>matched</strong>, so <strong>far</strong>, at <strong>left</strong> of the <strong>two</strong> verbs <strong><code>(*SKIP)(*FAIL)</code></strong>, in the <strong>current</strong> regex alternative !</p>
]]></description><link>https://community.notepad-plus-plus.org/post/55467</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/55467</guid><dc:creator><![CDATA[guy038]]></dc:creator><pubDate>Thu, 09 Nov 2023 14:24:21 GMT</pubDate></item><item><title><![CDATA[Reply to FAQ: Regex "Backtracking Control Verbs" on Thu, 09 Nov 2023 14:17:14 GMT]]></title><description><![CDATA[<pre><code class="language-diff">+            BACKTRACKING CONTROL verbs
-            THIRD post ( continuation )
</code></pre>
<h3>_______________ <strong><code>(*THEN)</code></strong> _______________</h3>
<p dir="auto"><code> </code></p>
<p dir="auto"><strong>Preliminary</strong> comment :</p>
<p dir="auto">I must confess that, among all the <strong>backtracking control</strong> verbs, the description and behavior of the <strong><code>(*THEN)</code></strong> verb, with our <strong><code>Boost</code></strong> regex engine, is a bit <strong>tricky</strong> and I still <strong>cannot</strong> explain some <strong>regex</strong> patterns, containing the <strong><code>(*THEN)</code></strong> verb. So, it quite <strong>possible</strong> that my general <strong>understanding</strong> of that <strong>specific</strong> verb is wrong … Just tell me !!</p>
<p dir="auto">The <strong><code>(*THEN)</code></strong> verb is generally used in an <strong>alternation</strong> structure. When the <strong><code>(*THEN)</code></strong> verb occurs <strong>outside</strong> an <strong>alternation</strong>, it behaves exactly like the <strong><code>(*PRUNE)</code></strong> verb</p>
<p dir="auto">In <strong><code>BOOST</code></strong> documentation, it is said :</p>
<blockquote>
<p dir="auto"><strong><code>(*THEN)</code></strong> has no effect unless <strong>backtracked</strong> onto, in which case <strong>all subsequent</strong> alternatives, in a <strong>group</strong> of alternations, are <strong>discarded</strong></p>
</blockquote>
<p dir="auto">This means that, if at <strong>current</strong> position in string, the <strong>regex</strong> engine can match the part <strong>before</strong> <strong><code>(*THEN)</code></strong> but <strong>cannot</strong> match the part <strong>after</strong> <strong><code>(*THEN)</code></strong>, of an <strong>alternative</strong>, in a group, as any <strong>backtracking</strong> is <strong>canceled</strong> to the <strong>left</strong> of <strong><code>(*THEN)</code></strong>, the <strong>current</strong> match attempt is <strong>discarded</strong> and all the <strong>subsequent</strong> alternatives of the <strong>current</strong> group. So, the regex engine skips to the pattern of the <strong>next</strong> alternative, located <strong>outside</strong> the <strong>current</strong> group</p>
<p dir="auto">The <strong><code>(*THEN)</code></strong> verb is a little <strong>confusing</strong> ! After, <strong>numerous</strong> tests to determine its <strong>true</strong> behavior, I came up with these explanations :</p>
<ul>
<li><strong>Only</strong> the <strong>first</strong> alternative, containing <strong><code>(*THEN)</code></strong>, as well as <strong>all</strong> alternatives <strong>without</strong> the <strong><code>(*THEN)</code></strong> verb, located or <strong>not</strong> in a group, are <strong>tried</strong> by the regex engine</li>
</ul>
<p dir="auto">And, in case of a <strong>backtracking</strong> at <strong>left</strong> of the <strong><code>(*THEN)</code></strong> verb of this <strong>first</strong> alternative :</p>
<ul>
<li>
<p dir="auto">If this alternative is located <strong>outside</strong> a group or is the <strong>single</strong> alternative of a <strong>group</strong>, <strong>without</strong> an alternation symbol <strong><code>|</code></strong>  :</p>
<ul>
<li>
<p dir="auto">The <strong>current</strong> group is <strong>not</strong> considered as a <strong>true</strong> group of alternatives</p>
</li>
<li>
<p dir="auto">Thus, the <strong><code>(*THEN)</code></strong> verb rather acts as a <strong><code>(*PRUNE)</code></strong> verb and the <strong>current</strong> starting position is <strong>increased</strong> by <strong><code>1</code></strong></p>
</li>
</ul>
</li>
<li>
<p dir="auto">If this alternative is located in a <strong>group</strong>, with, at least, <strong>two</strong> alternatives, with <strong><code>(*THEN)</code></strong>, separated by an <strong>alternation</strong> symbol <strong><code>|</code></strong> :</p>
<ul>
<li>
<p dir="auto">The <strong>current</strong> group is considered as a <strong>true</strong> group of <strong>alternatives</strong> and the semantics of the <strong><code>(*THEN)</code></strong> verb is <strong>activated</strong></p>
</li>
<li>
<p dir="auto">So, the <strong>current</strong> starting position remains <strong>unchanged</strong></p>
</li>
</ul>
</li>
<li>
<p dir="auto">Then, in <strong>both</strong> cases, the regex engine <strong>skips</strong> to the <strong>next</strong> alternative, <strong>outside</strong> the <strong>current</strong> group, whatever this one is <strong>included</strong> or <strong>not</strong> in a group</p>
</li>
</ul>
<hr />
<p dir="auto">For instance, let’s consider the <strong>regex</strong>, below, using the <strong>free-spacing</strong> mode :</p>
<pre><code class="language-z">(?x-i)
(  AB+(*THEN)CH  |  AB+(*THEN)CD  |  AB+(*THEN)CT  )  |  # Line 1
(  AB+(*THEN)ZE  |  AB+(*THEN)ZK                   )  |  # Line 2
(  \w{3}                                           )  |  # Line 3
(  AB+(*THEN)HA                                    )  |  # Line 4
(  AB+(*THEN)ZX  | AB+(*THEN)HY                    )     # Line 5
</code></pre>
<p dir="auto">against the <strong>one-line</strong> text, below, where the added <strong>numbers</strong>, designate <strong>each numbered</strong> occurrence :</p>
<pre><code class="language-z">ABBCD---ABBBBCH---ABBBBBCT---ABBBZK---ABBBBZE---ABBBBBZX---ABBBBHJ---ABHA---ABBBBBBHY---
111     2222222   333444     555666   7777777   888999     000111    222    333444555
</code></pre>
<p dir="auto">As you can see, only the <strong>first</strong> alternative of groups, line <strong><code>1</code></strong> and <strong><code>2</code></strong>, are taken in account, because, on <strong>backtracking</strong> to the <strong>left</strong> of <strong><code>(*THEN)</code></strong>, the regex engine then <strong>skips</strong>, immediately, to the <strong>next</strong> group of alternatives</p>
<p dir="auto">However, note that the <strong>first</strong> alternative of groups, line <strong><code>4</code></strong> and <strong><code>5</code></strong> are <strong>never</strong> tried because the <strong><code>\w{3}</code></strong> pattern comes <strong>before</strong> !</p>
<p dir="auto">So, except for the strings <strong>ABBBBCH</strong> and <strong>ABBBBZE</strong>, all the <strong>other</strong> strings are <strong>partially</strong> matched by the <strong><code>\w{3}</code></strong> pattern, line <strong><code>3</code></strong> !</p>
<hr />
<p dir="auto">Now, let’s consider the <strong>regex</strong>, below, in <strong>free-spacing</strong> mode :</p>
<pre><code class="language-z">(?x-i)
(  AB+(*THEN)CH  |  AB+(*THEN)CD  |  AB+(*THEN)CT  )  |  # Line 1
(  AB+(*THEN)ZE  |  AB+(*THEN)ZK                   )  |  # Line 2
(  AB+(*THEN)HA                                    )  |  # Line 3  Group WITHOUT an |  =&gt; (*THEN) acts as (*PRUNE)
(  \w{3}                                           )  |  # Line 4
(  AB+(*THEN)ZX  | AB+(*THEN)HY                    )     # Line 5
</code></pre>
<p dir="auto">against the <strong>same</strong> subject string :</p>
<pre><code class="language-z">ABBCD---ABBBBCH---ABBBBBCT---ABBBZK---ABBBBZE---ABBBBBZX---ABBBBHJ---ABHA---ABBBBBBHY---
 111    2222222    333444     555     6666666    777888     999000   1111    222333
</code></pre>
<p dir="auto">This time, <strong>only</strong> the <strong>first</strong> alternative of groups, line <strong><code>1</code></strong>, <strong><code>2</code></strong> and <strong><code>3</code></strong>, are taken in account, because, on <strong>backtracking</strong> to the <strong>left</strong> of <strong><code>(*THEN)</code></strong>, the regex engine then <strong>skips</strong>, immediately, to the <strong>next</strong> group of alternatives</p>
<p dir="auto">But, this time, due to the lack of any <strong>alternation</strong> symbol of the group, line <strong><code>3</code></strong>, the <strong>backtracking control</strong> verb <strong><code>(*THEN)</code></strong> acts rather as the <strong><code>(*PRUNE)</code></strong> verb. So, in case of a <strong>unsuccessful</strong> backtracking operation, the <strong>starting</strong> position of the regex engine advances to <strong>next</strong> position !</p>
<p dir="auto">Therefore, as the strings <strong>ABBCD</strong>, <strong>ABBBBBCT</strong>, <strong>ABBBZK</strong>, <strong>ABBBBBZX</strong>, <strong>ABBBBHJ</strong> and <strong>ABBBBBBHY</strong> cannot match the <strong><code>AB+(*THEN)HA</code></strong> pattern, in line <strong><code>3</code></strong>, the regex engine goes to <strong>next</strong> position, which always begins with a <strong>B</strong> letter.</p>
<p dir="auto">And, as <strong>all</strong> alternatives, beginning with an <strong><code>A</code></strong> letter, cannot match, the <strong><code>\w{3}</code></strong> pattern is the <strong>only</strong> one which can match something ( <strong><code>3</code></strong> <strong>consecutive</strong> letters )</p>
<hr />
<p dir="auto">Just compare with the same regex, <strong>without</strong> any <strong><code>(*THEN)</code></strong> verb, below, again the <strong>same</strong> string :</p>
<pre><code class="language-z">(?x-i)
(  AB+CH  |  AB+CD  |  AB+CT  )  |  # Line 1
(  AB+ZE  |  AB+ZK            )  |  # Line 2
(  AB+HA                      )  |  # Line 3
(  \w{3}                      )  |  # Line 4
(  AB+ZX  | AB+HY             )     # Line 5
</code></pre>
<p dir="auto">Note, again, the <strong>letters</strong> matched by <strong>each</strong> occurrence, keeping in mind that the regex engine, in that case, <strong>always</strong> tries the alternatives from <strong>left</strong> to <strong>right</strong>, period ! This explains why the strings <strong>ABBBBBZX</strong> and <strong>ABBBBBBHY</strong> are <strong>never</strong> matched by the patterns <strong><code>AB+ZX</code></strong> and <strong><code>AB+HY</code></strong></p>
<pre><code class="language-z">ABBCD---ABBBBCH---ABBBBBCT---ABBBZK---ABBBBZE---ABBBBBZX---ABBBBHJ---ABHA---ABBBBBBHY---
11111   2222222   33333333   444444   5555555   666777     888999    0000   111222333
</code></pre>
<hr />
<p dir="auto">As said before, if the <strong><code>(*THEN)</code></strong> verb is <strong>not</strong> inside an <strong>alternation</strong> group, it acts like the <strong><code>(*PRUNE)</code></strong> <strong>backtracking control</strong> verb.</p>
<p dir="auto">For instance, against the string <strong>---1123ABBBBCHIKOP---</strong> :</p>
<ul>
<li>
<p dir="auto">With the regex <strong><code>(?-i)\d+(AB+(*THEN)CD)|\w{8}</code></strong> or <strong><code>(?-i)\d+(AB+(*PRUNE)CD)|\w{8}+</code></strong>, containing a group, <strong>without</strong> any <strong>alternation</strong> symbol :</p>
<ul>
<li>
<p dir="auto">Because no <strong>D</strong> letter, right <strong>after</strong> the <strong>C</strong> letter, it <strong>fails</strong>, and, as <strong>backtracking</strong> is <strong>not</strong> allowed because of the verb <strong><code>(*THEN)</code></strong> or <strong><code>(*PRUNE) </code></strong>, the regex engine moves to the <strong>next</strong> starting position, in string, and retries the <strong>first</strong> alternative</p>
</li>
<li>
<p dir="auto">After <strong>successive</strong> moves to <strong>next</strong> starting position and immediate <strong>failure</strong> to match the <strong>CD</strong> string, caret is, now, <strong>right before</strong> the letter <strong>A</strong>. This time, the <strong>first</strong> alternative <strong>cannot</strong> match. So, the <strong>second</strong> alternative just matches the next <strong>eight</strong> characters <strong>ABBBBCHI</strong> :</p>
</li>
</ul>
</li>
</ul>
<pre><code class="language-z">---1123ABBBBCHIKOP---
       11111111
</code></pre>
<ul>
<li>
<p dir="auto">Now, with the regex <strong><code>(?x-i)\d+(AB+(*THEN)CD|\w\w)|\w{8}</code></strong>, containing a group with an <strong>alternation</strong> symbol :</p>
<ul>
<li>
<p dir="auto">After the <strong>failure</strong> in matching <strong>D</strong>, right <strong>after</strong> letter <strong>C</strong>, and, as backtracking on <strong><code>AB+</code></strong> is <strong>not</strong> allowed because of the verb <strong><code>(*THEN)</code></strong>, the regex engine skips and tries the <strong>next</strong> alternative of this <strong>inner</strong> group, <strong><code>\w\w</code></strong></p>
</li>
<li>
<p dir="auto">But, this time, the <strong>backtracking</strong> process onto <strong><code>\d+</code></strong> is possible, from the <strong>first</strong> position in string ( the regex engine must find a range of <strong>digits</strong>, not followed with the <strong>A</strong> letter). Thus, it easily finds the <strong>1123A</strong> string, where <strong><code>\d+</code></strong> = <strong>112</strong> and <strong><code>\w\w</code></strong> = <strong>3A</strong> :</p>
</li>
</ul>
</li>
</ul>
<pre><code class="language-z">---1123ABBBBCHIKOP---
   1111122222222
</code></pre>
<hr />
<p dir="auto">When the regex expression, located <strong>before</strong> a <strong><code>(*THEN)</code></strong> <strong>backtracking control</strong> verb, is complex and time-consuming, the <strong><code>(*THEN)</code></strong> verb acts in the same way as an <strong>atomic</strong> group, because it prevents from any <strong>backtracking</strong> in <strong>current</strong> used alternative. However the use of the <strong><code>(*THEN)</code></strong> verb seems <strong>limited</strong> and, personally, I haven’t found out, yet, any <strong>practical</strong> use of this verb !</p>
<p dir="auto">As I said before, my present <strong>reasoning</strong> about the <strong><code>(*THEN)</code></strong> <strong>backtracking control</strong> verb may be completely <strong>erroneous</strong>.Here are some <strong>oddities</strong> that I still <strong>cannot</strong> understand ! Can someone can explain me :</p>
<ul>
<li>
<p dir="auto">Why the regex <strong><code>(?-i)A(B+(*THEN)L|FK)|\w\w</code></strong> matches <strong>BX</strong>, in the string <strong>---ABX---</strong> ?</p>
</li>
<li>
<p dir="auto">and why the regex <strong><code>(?-i)A(B+(*THEN)L|BK)|\w\w</code></strong> matches  <strong>AB</strong>, in the same string <strong>---ABX---</strong> ?</p>
</li>
</ul>
<hr />
<p dir="auto"><strong>IMPORTANT</strong> : The <strong><code>4</code></strong> full <strong>backtracking control</strong> verbs, described, above, provide <strong><code>4</code></strong> different <strong>strengths</strong> of control when subsequent matching <strong>fails</strong> :</p>
<ul>
<li>
<p dir="auto">The <strong><code>(*THEN)</code></strong> is the <strong>weakest</strong>, carrying on the match at the <strong>next</strong> alternative, first</p>
</li>
<li>
<p dir="auto">The <strong><code>(*PRUNE)</code></strong> verb comes next, <strong>failing</strong> the match at the <strong>current</strong> starting position, even in case of subsequent <strong>alternatives</strong>, and moving, in string, to the <strong>next</strong> position</p>
</li>
<li>
<p dir="auto">The <strong><code>(*SKIP)</code></strong> verb is <strong>similar</strong> to <strong><code>(*PRUNE)</code></strong>, except that the regex engine moves, in string, to the <strong><code>(*SKIP)</code></strong> location ( so, possibly <strong>more than one</strong> character ! )</p>
</li>
<li>
<p dir="auto">Finally, the <strong><code>(*COMMIT)</code></strong> verb is the <strong>strongest</strong> and <strong>always</strong> causes the <strong>overall</strong> match to <strong>fail</strong></p>
</li>
</ul>
<p dir="auto">In <strong>next</strong> chapters, we’ll study the <strong>two</strong> verbs <strong><code>(*ACCEPT)</code></strong> and <strong><code>(*FAIL)</code></strong>. In contrast to the <strong>previous</strong> verbs, the <strong><code>(*ACCEPT)</code></strong> and <strong><code>(*FAIL)</code></strong> verbs act <strong>as soon as</strong> they are encountered !</p>
<hr />
<h3>_______________ <strong><code>(*ACCEPT)</code></strong> _______________</h3>
<p dir="auto"><code> </code></p>
<p dir="auto">In <strong><code>BOOST</code></strong> documentation, it is said :</p>
<blockquote>
<p dir="auto"><strong><code>(*ACCEPT)</code></strong> Causes the pattern to be considered <strong>matched</strong> at the <strong>current</strong> point. Any <strong>half-open</strong> sub-expressions are <strong>closed</strong> at the <strong>current</strong> point.</p>
</blockquote>
<p dir="auto">This means that, if at <strong>current</strong> position in string, the <strong>regex</strong> engine can match the part right <strong>before</strong> the <strong><code>(*ACCEPT)</code></strong> verb, this <strong>partial</strong> match is considered as a <strong>successful</strong> match attempt and <strong>any</strong> pattern, <strong>after</strong> the <strong><code>(*ACCEPT)</code></strong> verb, is simply <strong>discarded</strong>. Then, as usual, the <strong>regex</strong> engine advances to the <strong>next</strong> starting position, in string, for a <strong>new</strong> match attempt</p>
<p dir="auto">If the <strong><code>(*ACCEPT)</code></strong> <strong>backtracking control</strong> verb is located <strong>inside</strong> a <strong>capturing</strong> group, that group is set to <strong>whatever</strong> characters have been <strong>matched</strong>, <strong>up to</strong> that point !</p>
<p dir="auto">Let’s consider the regex <strong><code>\d+(*ACCEPT).+|\w+</code></strong>, against the string <strong>12345----abcde----</strong></p>
<ul>
<li>
<p dir="auto">First, the regex matches the digits <strong>12345</strong></p>
</li>
<li>
<p dir="auto">Without the <strong><code>(*ACCEPT)</code></strong> verb, the ending <strong><code>.+</code></strong> part of the <strong>current</strong> alternative would have matched <strong>all</strong> the <strong>remaining</strong> chars of line</p>
</li>
<li>
<p dir="auto">But, as soon as the <strong><code>(*ACCEPT)</code></strong> verb is reached, the <strong>current</strong> pattern, so far, <strong><code>\d+</code></strong>, is considered as <strong>successful</strong> and the ending <strong><code>.+</code></strong> part of the <strong>current</strong> alternative is <strong>discarded</strong> by the regex engine</p>
</li>
<li>
<p dir="auto">Then current starting  position is right before the <strong>first</strong> dash char, which <strong>cannot</strong> match the regex</p>
</li>
<li>
<p dir="auto">After moving till right <strong>after</strong> the <strong>last</strong> dash character, the <strong>second</strong> alternative does match the string <strong>abcde</strong></p>
</li>
</ul>
<p dir="auto">The interest of the <strong><code>(*ACCEPT)</code></strong> verb is generally <strong>limited</strong>. But, sometimes, it can be very <strong>useful</strong> when used in a list of <strong>alternatives</strong> !</p>
<hr />
<p dir="auto">A <strong>practical</strong> use is described on the [rexegg] (<a href="https://www.rexegg.com/backtracking-control-verbs.html#accept" rel="nofollow ugc">https://www.rexegg.com/backtracking-control-verbs.html#accept</a>) site :</p>
<p dir="auto">Let’s suppose you would like to match the <strong><code>3</code></strong> <strong>upper-case</strong> strings <strong>BAZ</strong>, <strong>BO</strong> and <strong>BIZ</strong>. Of course, an obvious solution is <strong><code>(?-i)BAZ|BO|BIZ</code></strong></p>
<p dir="auto">But, if <strong>B</strong> and <strong>Z</strong> stand for <strong>complicated</strong> sub-patterns, you would probably <strong>factor</strong> these <strong>two</strong> patterns, which is normally <strong>impossible</strong> because of the <strong>BO</strong> syntax.</p>
<p dir="auto">With the <strong><code>B(?:A|O(*ACCEPT)|I)Z</code></strong> syntax, containing the  <strong><code>(*ACCEPT)</code></strong> verb, the <strong>factorization</strong> of the <strong>B</strong> pattern, at the <strong>beginning</strong> and the <strong>Z</strong> pattern, at the <strong>end</strong> becomes possible !</p>
<p dir="auto">Indeed, when the regex engine uses the <strong>alternative</strong> <strong><code>O(*ACCEPT)</code></strong> ( so the <strong>overall</strong> regex  <strong><code>BO(*ACCEPT)Z</code></strong> ), it just matches the <strong>BO</strong> string as the match of <strong><code>Z</code></strong> is <strong>discarded</strong>, due to the <strong><code>(*ACCEPT)</code></strong> verb</p>
<p dir="auto">As usual, a solution <strong>without</strong> any <strong>backtracking control</strong> verb is still possible, with <strong>conditional</strong> patterns. You could use, either, the regexes below, with the <strong>conditional</strong> structure <strong><code>(?(1)...|...)</code></strong></p>
<p dir="auto">SEARCH <strong><code>B(?:(A|I)|O)(?(1)Z)</code></strong>    or    <strong><code>B(?:A|I|(O))(?(1)|Z)</code></strong></p>
<hr />
<p dir="auto">The <strong><code>(*ACCEPT)</code></strong> <strong>backtracking control</strong> verb is the <strong>only</strong> backtracking verb that is allowed to be <strong>quantified</strong>. And, when the quantifier is <strong>ungreeedy</strong>, this allows the <strong><code>(*ACCEPT)</code></strong> verb to acts <strong>only</strong> when a <strong>backtracking</strong> phase, from quantifier <strong><code>0</code></strong> to quantifier <strong><code>1</code></strong> occurs !</p>
<ul>
<li>
<p dir="auto">Consider the regex <strong><code>A(*ACCEPT)??BC</code></strong>, where the <strong><code>(*ACCEPT)</code></strong> verb is located <strong>inside</strong> an <strong>ungreedy</strong> quantified group, with a <strong>minimum</strong> of <strong><code>0</code></strong>, against the string <strong>AAAABCBBBBBAAAABCCCCCC</strong></p>
<ul>
<li>
<p dir="auto">If <strong>current</strong> starting point is right <strong>before</strong> an <strong>A</strong>, followed with <strong>BC</strong>, as the quantifier takes <strong>first</strong> the value <strong><code>0</code></strong> =&gt; the <strong><code>(*ACCEPT)</code></strong> verb is <strong>not</strong> taken in account. Thus, the regex is identical to <strong><code>ABC</code></strong> and matches the string <strong>ABC</strong>, in <strong>forward</strong> direction, <strong>without</strong> any backtracking process</p>
</li>
<li>
<p dir="auto">If an <strong>A</strong> is <strong>not</strong> followed by <strong>BC</strong>, at <strong>current</strong> starting position, a <strong>backtrack</strong> is needed and the value <strong><code>1</code></strong> is tried =&gt; Thus, the regex becomes <strong><code>A(*ACCEPT)B</code></strong> which <strong>always</strong> matches an <strong>A</strong> letter, in <strong>all</strong> cases</p>
</li>
</ul>
</li>
<li>
<p dir="auto">Now, consider the regex <strong><code>A(*ACCEPT)?BC</code></strong>, where the <strong><code>(*ACCEPT)</code></strong> verb is located <strong>inside</strong> a <strong>greedy</strong> quantified group, with a <strong>maximum</strong> of <strong><code>1</code></strong>, against the <strong>same</strong> string :</p>
<ul>
<li>This time, whether an <strong>A</strong> is followed or <strong>not</strong> with the string <strong>BC</strong>, at <strong>current</strong> starting point, as the quantifier takes <strong>first</strong> the value <strong><code>1</code></strong> =&gt; The <strong><code>(*ACCEPT)</code></strong> verb is <strong>always</strong> taken in account. So, the regex is identical to the pattern <strong><code>A(*ACCEPT)BC</code></strong>,  which <strong>always</strong> matches a <strong>A</strong> letter, in <strong>all</strong> cases</li>
</ul>
</li>
</ul>
]]></description><link>https://community.notepad-plus-plus.org/post/55466</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/55466</guid><dc:creator><![CDATA[guy038]]></dc:creator><pubDate>Thu, 09 Nov 2023 14:17:14 GMT</pubDate></item><item><title><![CDATA[Reply to FAQ: Regex "Backtracking Control Verbs" on Thu, 09 Nov 2023 14:30:21 GMT]]></title><description><![CDATA[<pre><code class="language-diff">+                  BACKTRACKING CONTROL verbs
-                 SECOND post ( continuation )
</code></pre>
<h3>_______________ <strong><code>(*SKIP)</code></strong> _______________</h3>
<p dir="auto"><code> </code></p>
<p dir="auto">In <strong><code>BOOST</code></strong> documentation, it is said :</p>
<blockquote>
<p dir="auto"><strong><code>(*SKIP)</code></strong> Behaves the same as <strong><code>(*PRUNE)</code></strong> except that it is assumed that <strong>no</strong> match can possibly occur <strong>prior</strong> to the current point in the string being searched. This can be used to <strong>optimize</strong> searches by <strong>skipping over</strong> chunks of text that have already been determined can <strong>not</strong> form a match.</p>
</blockquote>
<p dir="auto">This means that, if at <strong>current</strong> position in string, the <strong>regex</strong> engine can match the part <strong>before</strong> <strong><code>(*SKIP)</code></strong> but <strong>cannot</strong> match the part <strong>after</strong> <strong><code>(*SKIP)</code></strong>, as any <strong>backtracking</strong> is <strong>canceled</strong> to the <strong>left</strong> of <strong><code>(*SKIP)</code></strong>, the regex engine <strong>discards</strong> any further search and the <strong>current</strong> match attempt just <strong>fails</strong>. So the regex engine <strong>must</strong> advance to the location in the string coresponding to where <strong><code>(*SKIP)</code></strong> was matched, for the <strong>next</strong> new match attempt !</p>
<p dir="auto">In other words, if the <strong><code>(*SKIP)</code></strong> is <strong>crossed</strong>, during the <strong>backtracking</strong> process, the regex <strong>search</strong> process <strong>stops</strong>, at <strong>current</strong> position and begins again, at location <strong>right after</strong> the <strong><code>(*SKIP)</code></strong> verb. So, the text matched <strong>before</strong> <strong><code>(*SKIP)</code></strong> will <strong>never</strong> be part of a subsequent <strong>successful</strong> match ! Sometimes, this behavior can save a lot of <strong>fruitless</strong> match attempts !</p>
<hr />
<p dir="auto">Consider the regex <strong><code>(?-i)AB+(*SKIP)CD|\w{2}.|AB+(*SKIP)CH</code></strong>, against the text <strong>---ABBZE---ABBBBCH---ABBBCY---ABBBBCD---</strong></p>
<p dir="auto">So, according to the effect of a <strong><code>(*SKIP)</code></strong> <strong>backtracking control</strong> verb, let’s follow the regex engine’s work :</p>
<ul>
<li>
<p dir="auto">The <strong>first <code>3</code></strong> positions of the string ( <strong><code>\-\-\-</code></strong> ) are skipped, as <strong>no</strong> alternative can match a <strong>dash</strong> character</p>
</li>
<li>
<p dir="auto">So, the <strong>starting</strong> position is right <strong>before</strong> the string <strong>ABBZE</strong> :</p>
<ul>
<li>
<p dir="auto">The <strong>first</strong> found pattern <strong><code>AB+(*SKIP)CD</code></strong> matches <strong>ABB</strong> but cannot match <strong><code>CD</code></strong></p>
</li>
<li>
<p dir="auto">So, it tries to <strong>backtrack</strong> at <strong>left</strong> of the <strong><code>(*SKIP)</code></strong> syntax to test <strong>other</strong> values of <strong><code>AB+</code></strong></p>
</li>
<li>
<p dir="auto">Because of the <strong><code>(*SKIP)</code></strong> control verb, this behavior is <strong>forbidden</strong> So, all which is matched, so far ( <strong><code>ABB</code></strong> ), is <strong>discarded</strong> and the regex engine moves to the location where <strong><code>(*SKIP)</code></strong> occurs, so right <strong>after</strong> the <strong>ABB</strong> string</p>
</li>
</ul>
</li>
<li>
<p dir="auto">Now, the <strong>starting</strong> position is right before the string <strong>ZE</strong> :</p>
</li>
<li>
<p dir="auto">The <strong>first</strong> alternative <strong>cannot</strong> match in <strong>forward</strong> direction but the <strong>second</strong> one <strong><code>\w{2}.</code></strong> does match the string <strong>ZE-</strong></p>
</li>
<li>
<p dir="auto">So, after <strong><code>2</code></strong> moves, again, the <strong>starting</strong> position is, now, right before the string <strong>ABBBBCH</strong> :</p>
<ul>
<li>
<p dir="auto">At this stage, it’s worth noting that <strong>last</strong> alternative <strong><code>AB+(*SKIP)CH</code></strong> could match the <strong>ABBBBCH</strong> string ! However it won’t be used, because the <strong>first</strong> alternative <strong><code>AB+(*SKIP)CD</code></strong> is tested <strong>first</strong></p>
</li>
<li>
<p dir="auto">So, the <strong>first</strong> found pattern <strong><code>AB+(*SKIP)CD</code></strong> matches <strong>ABBBB</strong> but cannot match <strong><code>CD</code></strong></p>
</li>
<li>
<p dir="auto">So, it tries to <strong>backtrack</strong> at <strong>left</strong> of the <strong><code>(*SKIP)</code></strong> syntax to test <strong>other</strong> values of <strong><code>AB+</code></strong></p>
</li>
<li>
<p dir="auto">Because of the <strong><code>(*SKIP)</code></strong> control verb, this behavior is <strong>forbidden</strong> So, all which is matched, so far ( <strong><code>ABBBB</code></strong> ), is <strong>discarded</strong> and the regex engine moves to the location where <strong><code>(*SKIP)</code></strong> occurs, so right <strong>after</strong> the <strong>ABBBB</strong> string</p>
</li>
</ul>
</li>
<li>
<p dir="auto">Now, the <strong>starting</strong> position is right before the string <strong>CH</strong> :</p>
</li>
<li>
<p dir="auto">Again, the <strong>first</strong> alternative <strong>cannot</strong> match in <strong>forward</strong> direction but the <strong>second</strong> one, <strong><code>\w{2}.</code></strong>, does match the string <strong>CH-</strong></p>
</li>
<li>
<p dir="auto">After <strong><code>2</code></strong> moves, the <strong>starting</strong> position is, now, right before the string <strong>ABBBCY</strong> :</p>
<ul>
<li>
<p dir="auto">Process is <strong>identical</strong> as it was when the <strong>starting</strong> position was right before the string <strong>ABBZE</strong></p>
</li>
<li>
<p dir="auto">Because of the <strong><code>(*SKIP)</code></strong> control verb, <strong>current</strong> match attempt <strong>fails</strong> and the regex engine moves to the location where <strong><code>(*SKIP)</code></strong> occurs, so right <strong>before</strong> the string <strong>CY</strong> :</p>
</li>
</ul>
</li>
<li>
<p dir="auto">The <strong>first</strong> alternative fails, in <strong>forward</strong> direction but the <strong>second</strong> pattern <strong><code>\w{2}.</code></strong> does match the string <strong>CY-</strong></p>
</li>
<li>
<p dir="auto">Finally, after <strong><code>2</code></strong> moves, the <strong>starting</strong> position is, now, right before the string <strong>ABBBBCD</strong> :</p>
<ul>
<li>This time, the <strong>first</strong> alternative <strong><code>AB+(*SKIP)CD</code></strong> just matches, in <strong>forward</strong> direction, all the <strong>remaining</strong> letters, the string <strong>ABBBBCD</strong></li>
</ul>
</li>
</ul>
<p dir="auto">See, below, the <strong>letters</strong> matched by each <strong>numbered</strong> occurrence :</p>
<pre><code class="language-z">---ABBZE---ABBBBCH---ABBBCY---ABBBBCD---
      111       222      333  4444444
</code></pre>
<p dir="auto">Just compare with the <strong>same</strong> regex, below,  where we <strong>omit</strong> the <strong><code>(*SKIP)</code></strong> control verb :</p>
<p dir="auto"><strong><code>(?-i)AB+CD|\w{2}.|AB+CH</code></strong></p>
<p dir="auto">Note, again, the <strong>letters</strong> matched by <strong>each</strong> occurrence, keeping in mind that the regex engine, in that case, <strong>always</strong> tries the alternatives from <strong>left</strong> to <strong>right</strong>, period !</p>
<pre><code class="language-z">---ABBZE---ABBBBCH---ABBBCY--ABBBBCD----
   111222  333444    555666  7777777
</code></pre>
<hr />
<p dir="auto">A <strong>second</strong> example : against the string <strong>aaacaaabxxaacaaaa---</strong>, beginning a line, let’s test some regexes :</p>
<ul>
<li>
<p dir="auto">The regex <strong><code>\w+(*SKIP)b|.+</code></strong> :</p>
<ul>
<li>
<p dir="auto">First this regex matches <strong>all</strong> the letters <strong>aaacaaabxxaacaaaa</strong> and tries to <strong>backtrack</strong> in order to get a final <strong>b</strong> letter</p>
</li>
<li>
<p dir="auto">As the <strong>backtracking</strong> process is <strong>forbidden</strong> because of the <strong><code>(*SKIP)</code></strong> control verb, current match attempt <strong>fails</strong></p>
</li>
<li>
<p dir="auto">Then, the <strong>starting</strong> position moves to the location where <strong><code>(*SKIP)</code></strong> is encountered, so right <strong>after all</strong> the letters</p>
</li>
<li>
<p dir="auto">Finally, as the <strong>first</strong> alternative does <strong>not</strong> match, the <strong>second</strong> alternative <strong><code>.+</code></strong>	 does match the string <strong>---</strong></p>
</li>
</ul>
</li>
</ul>
<pre><code class="language-z">aaacaaabxxaacaaaa---
                 111
</code></pre>
<ul>
<li>
<p dir="auto">The regex <strong><code>a+(*SKIP)b|.+</code></strong> :</p>
<ul>
<li>
<p dir="auto">First this regex matches <strong>all</strong> the letters <strong>aaa</strong> and, as the next <strong>c</strong> letter does <strong>not</strong> match the <strong><code>b</code></strong> pattern, it tries to <strong>backtrack</strong></p>
</li>
<li>
<p dir="auto">As the <strong>backtracking</strong> process is <strong>forbidden</strong> because of the <strong><code>(*SKIP)</code></strong> control verb, current match attempt <strong>fails</strong></p>
</li>
<li>
<p dir="auto">Then, the <strong>starting</strong> position moves to the location where <strong><code>(*SKIP)</code></strong> is encountered, so right <strong>after</strong> the <strong>aaa</strong> string</p>
</li>
<li>
<p dir="auto">Finally, as the <strong>first</strong> alternative <strong>cannot</strong> match, the <strong>second</strong> alternative <strong><code>.+</code></strong> alternative <strong>does</strong> match the <strong>remaining</strong> characters <strong>caaabxxaacaaaa---</strong></p>
</li>
</ul>
</li>
</ul>
<pre><code class="language-z">aaacaaabxxaacaaaa---
   11111111111111111
</code></pre>
<p dir="auto">See the <strong>differences</strong> with the <strong>similar</strong> regexes, without the <strong><code>(*SKIP)</code></strong> control verb :</p>
<ul>
<li>
<p dir="auto">The regex <strong><code>\w+b|.+</code></strong></p>
<ul>
<li>
<p dir="auto">First this regex matches <strong>all</strong> the letters and, as the next <strong>-</strong> character does <strong>not</strong> match the <strong><code>b</code></strong> pattern, it <strong>backtracks</strong> from the last <strong>a</strong> letter to the letter <strong>a</strong>, before the <strong>b</strong> letter, for a <strong>first</strong> match <strong>aaacaaab</strong></p>
</li>
<li>
<p dir="auto">Then, as the <strong>first</strong> alternative <strong>cannot</strong> match, the second alternative <strong><code>.+</code></strong> matches all the <strong>remaining</strong> characters, so the string <strong>xxaacaaaa---</strong></p>
</li>
</ul>
</li>
</ul>
<pre><code class="language-z">aaacaaabxxaacaaaa---
11111111222222222222
</code></pre>
<ul>
<li>
<p dir="auto">The regex <strong><code>\w+?b|.+</code></strong></p>
<ul>
<li>
<p dir="auto">First this regex matches the first letter <strong>a</strong>  and, as the next <strong>a</strong> letter does <strong>not</strong> match the <strong><code>b</code></strong> pattern, it backtracks from the first <strong>a</strong> letter to the letter <strong>a</strong>, before the letter <strong>b</strong>, for a <strong>first</strong> match <strong>aaacaaab</strong></p>
</li>
<li>
<p dir="auto">Then, as the <strong>first</strong> alternative <strong>cannot</strong> match, the second alternative <strong><code>.+</code></strong> matches all the <strong>remaining</strong> characters <strong>xxaacaaaa---</strong>, as above</p>
</li>
</ul>
</li>
<li>
<p dir="auto">The regex <strong><code>\w++b|.+</code></strong></p>
<ul>
<li>
<p dir="auto">First this regex matches <strong>all</strong> the letters and, as the next <strong>-</strong> character does <strong>not</strong> match the <strong><code>b</code></strong> pattern, the regex engine tries to <strong>backtrack</strong></p>
</li>
<li>
<p dir="auto">But, because of the <strong>possessive</strong> quantifier <strong><code>++</code></strong>, the <strong>backtracking</strong> process is <strong>not</strong> allowed and the match attempt <strong>fails</strong></p>
</li>
<li>
<p dir="auto">So, the <strong>second</strong> alternative <strong><code>.+</code></strong> is tried and matches all the <strong>remaining</strong> characters, so the <strong>entire</strong> string <strong>aaacaaabxxaacaaaa---</strong></p>
</li>
</ul>
</li>
</ul>
<hr />
<p dir="auto">Note that, on <a href="https://www.rexegg.com/backtracking-control-verbs.html#doublebomb" rel="nofollow ugc">Rexegg site</a> , it is said :</p>
<blockquote>
<p dir="auto">If <strong><code>(*SKIP)</code></strong> is the <strong>last</strong> backtracking control verb in a template, a match <strong>failure</strong> beyond <strong><code>(*SKIP)</code></strong> should, in principle, always <strong>trigger</strong> the <strong><code>(*SKIP)</code></strong> control verb. Indeed, <strong>backtracking</strong> is needed to test <strong>new</strong> match attempts at <strong>current</strong> position in string !</p>
</blockquote>
<blockquote>
<p dir="auto">In practice, internally, among all kinds of clever <strong>optimizations</strong>, <strong><code>Perl</code></strong>, <strong><code>PCRE</code></strong> and <strong><code>Python</code></strong>’s regex package are smart enough to avoid <strong>fruitless</strong> backtracking. But <strong>externally</strong>, <strong><code>PCRE</code></strong> and <strong><code>Python</code></strong> behave as though they were <strong>backtracking</strong> all the way back</p>
</blockquote>
<p dir="auto">This seems <strong>also</strong> the behavior of the <strong><code>Boost</code></strong> regex engine. If these <strong>optimizations</strong> had been taken into account, the regex engine would have behaved, sometimes, as if <strong>no</strong> <strong><code>(*SKIP)</code></strong> <strong>backtracking control</strong> verb was part of the <strong>overall</strong> regex</p>
<p dir="auto">Now, regarding <strong>practical</strong> uses of the <strong><code>(*SKIP)</code></strong> <strong>backtracking control</strong> verb, we can mention the <strong>association</strong> of this verb with the verb <strong><code>(*FAIL)</code></strong>, which will be studied <strong>later</strong></p>
<hr />
<h3>_______________ <strong><code>(*PRUNE)</code></strong> _______________</h3>
<p dir="auto"><code> </code></p>
<p dir="auto">In <strong><code>BOOST</code></strong> documentation, it is said :</p>
<blockquote>
<p dir="auto"><strong><code>(*PRUNE)</code></strong> Has no effect unless <strong>backtracked</strong> onto, in which case all the <strong>backtracking</strong> information, <strong>prior</strong> to this point, is <strong>discarded.</strong></p>
</blockquote>
<p dir="auto">This means that, if at <strong>current</strong> position in string, the <strong>regex</strong> engine can match the part <strong>before</strong> <strong><code>(*PRUNE)</code></strong> but <strong>cannot</strong> match the part <strong>after</strong> <strong><code>(*PRUNE)</code></strong>, as any <strong>backtracking</strong> is <strong>canceled</strong> to the <strong>left</strong> of <strong><code>(*PRUNE)</code></strong>, the regex engine <strong>discards</strong> any further search and the <strong>current</strong> match attempt just <strong>fails</strong>. Thus, the regex engine then advances to <strong>next</strong> position, in the string, for a <strong>new</strong> match attempt</p>
<p dir="auto">In other words, if the <strong><code>(*PRUNE)</code></strong> is <strong>crossed</strong>, during the <strong>backtracking</strong> process, the regex <strong>search</strong> process <strong>stops</strong>, at <strong>current</strong> position and process <strong>begins</strong> again, at <strong>next</strong> starting position, in string !</p>
<p dir="auto">Usually, the <strong><code>(*PRUNE)</code></strong> verb is simply an alternative to an <strong>atomic</strong> group or to a <strong>possessive</strong> quantifier. However, there are some uses of the <strong><code>(*PRUNE)</code></strong> verb that <strong>cannot</strong> be expressed in <strong>any other</strong> way !</p>
<hr />
<p dir="auto">Consider the regex <strong><code>(?-i)AB+(*PRUNE)CD|\w{3}|AB+(*PRUNE)CH</code></strong>, against the text <strong>---ABBZE---ABBBBCH---ABBBCY---ABBBBCD---</strong></p>
<p dir="auto">So, according to the effect of a <strong><code>(*PRUNE)</code></strong> <strong>backtracking control</strong> verb, let’s follow the regex engine’s work :</p>
<ul>
<li>
<p dir="auto">The <strong>first <code>3</code></strong> positions of the string ( <strong>---</strong> ) are skipped, as <strong>no</strong> alternative can match a <strong>dash</strong> character</p>
</li>
<li>
<p dir="auto">So, the <strong>starting</strong> position is right before the string <strong>ABBZE</strong> :</p>
<ul>
<li>
<p dir="auto">The <strong>first</strong> found pattern <strong><code>AB+(*PRUNE)CD</code></strong> matches <strong>ABB</strong> but cannot match <strong>CD</strong></p>
</li>
<li>
<p dir="auto">So, it tries to <strong>backtrack</strong> at <strong>left</strong> of the <strong><code>(*PRUNE)</code></strong> syntax to test <strong>other</strong> values of <strong><code>AB+</code></strong></p>
</li>
<li>
<p dir="auto">Because of the <strong><code>(*PRUNE)</code></strong> control verb, this behavior is <strong>forbidden</strong> So, all which is matched, so far ( <strong><code>ABB</code></strong> ), is <strong>discarded</strong> and the regex engine moves to the next <strong>starting</strong> position, in string. So, <strong>right before</strong> the string <strong>BBZE</strong></p>
</li>
</ul>
</li>
<li>
<p dir="auto">The <strong>first</strong> alternative <strong>cannot</strong> match in <strong>forward</strong> direction but the <strong>second</strong> alternative <strong><code>\w{3}</code></strong> does match the string <strong>BBZ</strong></p>
</li>
<li>
<p dir="auto">Then, the <strong>starting</strong> position is right <strong>before</strong> the letter <strong>E</strong>, which <strong>cannot</strong> be matched by any part of the <strong>overall</strong> regex</p>
</li>
<li>
<p dir="auto">So, after <strong><code>3</code></strong> moves, again, the <strong>starting</strong> position is, now, right before the string <strong>ABBBBCH</strong> :</p>
<ul>
<li>
<p dir="auto">At this stage it’s worth noting that <strong>last</strong> alternative <strong><code>AB+(*PRUNE)CH</code></strong> could match the <strong>ABBBBCH</strong> string ! However it won’t be used, because the <strong>first</strong> alternative <strong><code>AB+(*PRUNE)CD</code></strong> is tried <strong>first</strong></p>
</li>
<li>
<p dir="auto">So, the <strong>first</strong> found pattern <strong><code>AB+(*PRUNE)CD</code></strong> matches <strong>ABBBB</strong> but cannot match <strong>CD</strong></p>
</li>
<li>
<p dir="auto">So, it tries to <strong>backtrack</strong> at <strong>left</strong> of the <strong><code>(*PRUNE)</code></strong> syntax to test <strong>other</strong> values of <strong><code>AB+</code></strong></p>
</li>
<li>
<p dir="auto">Because of the <strong><code>(*PRUNE)</code></strong> control verb, this behavior is <strong>forbidden</strong> So, all which is matched, so far ( <strong><code>ABBBB</code></strong> ), is <strong>discarded</strong> and the regex engine moves, immediately, to the next <strong>starting</strong> position, in string. So right <strong>before</strong> the string <strong>BBBBCH</strong></p>
</li>
</ul>
</li>
<li>
<p dir="auto">Again, the <strong>first</strong> alternative <strong>cannot</strong> match in <strong>forward</strong> direction but the <strong>second</strong> one, <strong><code>\w{3}</code></strong>, does match the string <strong>BBB</strong></p>
</li>
<li>
<p dir="auto">Then, the <strong>starting</strong> position is right before the string <strong>BCH</strong> :</p>
</li>
<li>
<p dir="auto">The <strong>first</strong> alternative <strong>cannot</strong> match, in <strong>forward</strong> direction, but the <strong>second</strong> alternative, <strong><code>\w[3}</code></strong>, does match the string <strong>BCH</strong></p>
</li>
<li>
<p dir="auto">After <strong><code>3</code></strong> moves, the <strong>starting</strong> position is, now, right <strong>before</strong> the string <strong>ABBBCY</strong> :</p>
<ul>
<li>
<p dir="auto">Process is <strong>identical</strong> as it was when the <strong>starting</strong> position was right before the string <strong>ABBZE</strong></p>
</li>
<li>
<p dir="auto">Because of the <strong><code>(*PRUNE)</code></strong> control verb, <strong>current</strong> match attempt <strong>fails</strong> and the regex engine moves to the <strong>next</strong> starting position, right <strong>before</strong> the string <strong>BBBCY</strong></p>
</li>
<li>
<p dir="auto">The <strong>first</strong> alternative fails, in <strong>forward</strong> direction but the <strong>second</strong> pattern <strong><code>\w{3}</code></strong> does match the string <strong>BBB</strong></p>
</li>
</ul>
</li>
<li>
<p dir="auto">Then, the <strong>starting</strong> position is right <strong>before</strong> the string <strong>CY</strong>, which <strong>cannot</strong> be matched by any part of the <strong>overall</strong> regex</p>
</li>
<li>
<p dir="auto">Finally, after <strong><code>3</code></strong> moves, the <strong>starting</strong> position is, now, right <strong>before</strong> the string <strong>ABBBBCD</strong> :</p>
<ul>
<li>This time, the <strong>first</strong> alternative <strong><code>AB+(*PRUNE)CD</code></strong> just matches, in <strong>forward</strong> direction, all the <strong>remaining</strong> letters, the string <strong>ABBBBCD</strong></li>
</ul>
</li>
</ul>
<p dir="auto">See, below, the <strong>letters</strong> matched by each <strong>numbered</strong> occurrence :</p>
<pre><code class="language-z">---ABBZE---ABBBBCH---ABBBCY---ABBBBCD---
    111     222333    444     5555555
</code></pre>
<p dir="auto">Just compare with the <strong>same</strong> regex, below,  where we <strong>omit</strong> the <strong><code>(*PRUNE)</code></strong> control verb :</p>
<p dir="auto"><strong><code>(?-i)AB+CD|\w{3}|AB+CH</code></strong></p>
<p dir="auto">Note, again, the <strong>letters</strong> matched by <strong>each</strong> occurrence, keeping in mind that the regex engine, in that case, <strong>always</strong> tries the alternatives from <strong>left</strong> to <strong>right</strong>, period !</p>
<pre><code class="language-z">---ABBZE---ABBBBCH---ABBBCY--ABBBBCD---
   111     222333    444555  5555555
</code></pre>
<hr />
<p dir="auto">If the regex part, located at left of a <strong><code>(*PRUNE)</code></strong> backtracking control verb is moderately <strong>complex</strong> and that a lot of <strong>backtracking</strong> actions are probable, it may save the regex engine a lot a time because it <strong>cancels</strong> any <strong>backtracking</strong> process and skips to next <strong>starting</strong> position, in string</p>
<p dir="auto">However, in this case, in order for <strong><code>(*PRUNE)</code></strong> to become <strong>efficient</strong>, note that :</p>
<ul>
<li>
<p dir="auto">All <strong>backtracking</strong> time must be <strong>greater</strong> that time to <strong>compile</strong> the pattern with this special verb</p>
</li>
<li>
<p dir="auto">Our <strong><code>Boost</code></strong> regex engine may have performed some internal <strong>optimizations</strong> that prevents <strong>backtracking</strong>, anyway</p>
</li>
<li>
<p dir="auto">Sometimes, the use of the <strong><code>(*SKIP)</code></strong> <strong>backtracking control</strong> verb is even <strong>better</strong> !</p>
</li>
</ul>
<hr />
<p dir="auto">Personally, I don’t see any <strong>practical</strong> use of the <strong><code>(*PRUNE)</code></strong> <strong>backtracking control</strong> verb, yet :-((</p>
<p dir="auto">One more point :</p>
<p dir="auto">In <strong>PCRE2</strong>, it is said :</p>
<blockquote>
<p dir="auto">In an <strong>anchored</strong> pattern <strong><code>(*PRUNE)</code></strong> has the <strong>same</strong> effect as <strong><code>(*COMMIT)</code></strong></p>
</blockquote>
<p dir="auto">Seemingly, it’s <strong>not</strong> the case, with our <strong><code>Boost</code></strong> regex engine, <strong>whatever</strong> the pattern is <strong>anchored</strong> or <strong>not</strong> :</p>
<p dir="auto">For instance, against the simple line : <strong>BBBBCX---</strong></p>
<ul>
<li>
<p dir="auto">The regex <strong><code>B+(*PRUNE)CD|.+</code></strong> matches the string <strong>CX---</strong>, but the regex <strong><code>B+(*COMMIT)CD|.+</code></strong> just <strong>fails</strong></p>
</li>
<li>
<p dir="auto">The regex <strong><code>^B+(*PRUNE)CD|.+</code></strong>, with an <strong>anchored</strong> pattern, matches the string <strong>BBBCX---</strong>*, but the regex <strong><code>^B+(*COMMIT)CD|.+</code></strong> <strong>fails</strong>, also</p>
</li>
</ul>
]]></description><link>https://community.notepad-plus-plus.org/post/55465</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/55465</guid><dc:creator><![CDATA[guy038]]></dc:creator><pubDate>Thu, 09 Nov 2023 14:30:21 GMT</pubDate></item></channel></rss>