<?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[Generic Regex: Logic Gates for Regular Expressions]]></title><description><![CDATA[<p dir="auto">There are times that you want specific logic in your regular expression, to handle combining two or more conditions in certain ways.  For example, you might want to match only lines that contain <code>cake</code> or <code>cookie</code>, but that don’t also contain <code>biscuit</code>; logically, this would be expressed as “match (<code>cake</code> OR <code>cookie</code>) AND (NOT <code>biscuit</code>)”.</p>
<p dir="auto">The following expressions use positive lookaheads for saying “it must match” and negative lookaheads for saying “it must not match” (logical “NOT”).  By using lookaheads with <code>.*</code> at the start, it means that it can be found anywhere on the line (or file) in any order.  But it also doesn’t consume anything, so alone, these expressions are “zero width”.</p>
<p dir="auto">If <code>☐ . matches newline</code> is not checked (☐), or if <code>(?-s)</code> is enabled in your regex, then those expressions will mean “a single line matches the logic expression chosen”.  if <code>☑ . matches newline</code> is checked (☑) (or <code>(?s)</code> is enabled in your regex), then those expressions will mean “the whole file matches the logic expression chosen”.</p>
<p dir="auto">All these expresions require <code>Search Mode = ☑ Regular Expression</code> to work.</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>logic</th>
<th>two-term expression</th>
<th>n-term expression</th>
<th>notes</th>
</tr>
</thead>
<tbody>
<tr>
<td>OR</td>
<td><code>(?=.*aaa|.*bbb)</code></td>
<td><code>(?=.*aaa|.*bbb|...|.*nnn)</code></td>
<td>must match at least one</td>
</tr>
<tr>
<td>AND</td>
<td><code>(?=.*aaa)(?=.*bbb)</code></td>
<td><code>(?=.*aaa)(?=.*bbb)...(?=.*nnn)</code></td>
<td>must match all</td>
</tr>
<tr>
<td>XOR</td>
<td><code>(?=.*aaa)(?!.*bbb)|(?!.*aaa)(?=.*bbb)</code></td>
<td>too complicated</td>
<td>match one or the other, but not both</td>
</tr>
<tr>
<td>NOR</td>
<td><code>(?!.*aaa)(?!.*bbb)</code></td>
<td><code>(?!.*aaa)(?!.*bbb)...(?!.*nnn)</code></td>
<td>matches neither one nor the other</td>
</tr>
<tr>
<td>NOR</td>
<td><code>(?!.*(aaa|bbb))</code></td>
<td><code>(?!.*(aaa|bbb|...|nnn))</code></td>
<td>second syntax for the same concept</td>
</tr>
<tr>
<td>NAND</td>
<td><code>(?!(?=.*aaa)(?=.*bbb))</code></td>
<td><code>(?!(?=.*aaa)(?=.*bbb)...(?=.*nnn))</code></td>
<td>may match zero or one of the terms, but not both</td>
</tr>
</tbody>
</table>
<p dir="auto">In case it’s not obvious, <code>aaa</code> and <code>bbb</code> and <code>nnn</code> are meant as placeholders for the terms or regex sub-expressions that you’re actually trying to combine.</p>
<p dir="auto">If you actually want to select the whole line, you cannot just use the zero-width forms above.  Instead, you would use <code>(?-s)(?:×××)^.*$</code> (where the ××× is the two-term or n-term expression): the <code>(?-s)</code> will force it to contain the match on a single-line (by making the <code>.</code> wildcard not match newlines), the <code>(?:×××)</code> will add the logic expression that you derived from the table, and the <code>^.*$</code> will cause it to actually match the whole line, rather than the zero-width sequence at the start of the line.</p>
<p dir="auto">Similarly, if you want to <strong>Find in Files</strong> to figure out which files match the logic expression, you can use <code>(?s)\A^(×××).</code>, where <code>(?s)</code> will make <code>.</code> match newlines, so the <code>.*</code> in each of the logic terms can match anywhere in the file; then the <code>\A</code> will match only at the start of the file, the <code>(×××)</code> will do the logic on the whole file; and the <code>.</code> will mean that it actually marks/matches the first character in each of the files it finds (which will make it actually report something in the <strong>Find Results</strong> after running <strong>Find in Files</strong>).</p>
<h2>Examples</h2>
<p dir="auto">With the <code>(?-s)(?:×××)^.*$</code> given above, if you chose the “two-term expression” and had the literal <code>aaa</code> and <code>bbb</code> as your search terms, the following “truth table” will show a T on the conditions that would match:</p>
<pre><code>text          | OR | AND | XOR | NOR | NOR | NAND
--------------|----+-----+-----+-----+-----+------
aaa other aaa | T  |     | T   |     |     | T
aaa other bbb | T  | T   |     |     |     |
aaa other ccc | T  |     | T   |     |     | T
bbb other aaa | T  | T   |     |     |     | 
bbb other bbb | T  |     | T   |     |     | T
bbb other ccc | T  |     | T   |     |     | T
ccc other aaa | T  |     | T   |     |     | T
ccc other bbb | T  |     | T   |     |     | T
ccc other ccc |    |     |     | T   | T   | T
</code></pre>
<p dir="auto">In other words, the text <code>aaa other aaa</code> will be matched by the OR expression <code>(?=.*aaa|.*bbb)</code>, or by the XOR expression <code>(?=.*aaa)(?!.*bbb)|(?!.*aaa)(?=.*bbb)</code>, or by the NAND expression <code>(?!(?=.*aaa)(?=.*bbb))</code>. (Similar interpretation for the other rows in the truth table.)</p>
<p dir="auto">For a more concrete example,</p>
<pre><code>I baked a cake.
The Brits call some cookies "biscuits".
I ate a cookie.
The fridge contains one cake and one cookie.
</code></pre>
<p dir="auto">With the expression <code>(?-s)(?:(?=.*cake|.*cookie)(?!.*biscuit))^.*$</code>, says “(<code>cake</code> OR <code>cookie</code>) AND NOT <code>biscuit</code>”, which was my first example of what you might want to implement.  In this text, the first, third, and fourth lines would match, but the second line would not match (because it contains <code>biscuit</code>).  This also give an example of how to combine multiple of the logic conditions together in one expression</p>
<p dir="auto">And <a class="plugin-mentions-user plugin-mentions-a" href="/user/alan-kilborn" aria-label="Profile: Alan-Kilborn">@<bdi>Alan-Kilborn</bdi></a> came up with the following example:<br />
Say you want to match some particular combination of <code>Bob</code> and <code>Ted</code> on a line – here’s examples on how to do that:</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Logic</th>
<th>Expression to use</th>
<th>Match entire line when…</th>
</tr>
</thead>
<tbody>
<tr>
<td>OR</td>
<td><code>(?-s)(?:(?=.*Bob|.*Ted))^.*(?:\R|\z)</code></td>
<td><code>Bob</code> or <code>Ted</code> (or both) is present, in either order</td>
</tr>
<tr>
<td>AND</td>
<td><code>(?-s)(?:(?=.*Bob)(?=.*Ted))^.*(?:\R|\z)</code></td>
<td>both <code>Bob</code> and <code>Ted</code> are present, in either order</td>
</tr>
<tr>
<td>XOR</td>
<td><code>(?-s)(?:(?=.*Bob)(?!.*Ted)|(?!.*Bob)(?=.*Ted))^.*(?:\R|\z)</code></td>
<td><code>Bob</code> or <code>Ted</code> is present, but not when both are present</td>
</tr>
<tr>
<td>NOR-1</td>
<td><code>(?-s)(?:(?!.*Bob)(?!.*Ted))^.*(?:\R|\z)</code></td>
<td>neither <code>Bob</code>/<code>Ted</code> are present (form 1)</td>
</tr>
<tr>
<td>NOR-2</td>
<td><code>(?-s)(?:(?!.*(Bob|Ted)))^.*(?:\R|\z)</code></td>
<td>neither <code>Bob</code>/<code>Ted</code> are present (form 2)</td>
</tr>
<tr>
<td>NAND</td>
<td><code>(?-s)(?:(?!(?=.*Bob)(?=.*Ted)))^.*(?:\R|\z)</code></td>
<td>neither are present or one is present, but not when both are present</td>
</tr>
</tbody>
</table>
<h2>References</h2>
<p dir="auto">Originally developed in <a href="https://community.notepad-plus-plus.org/post/67136">developing generic regex sequences</a> and subsequent discussion</p>
<p dir="auto">For other generic expressions, see <a href="https://community.notepad-plus-plus.org/topic/22673/faq-desk-generic-regular-expression-regex-formulas">FAQ Desk: Generic Regular Expression (regex) Formulas</a></p>
]]></description><link>https://community.notepad-plus-plus.org/topic/22677/generic-regex-logic-gates-for-regular-expressions</link><generator>RSS for Node</generator><lastBuildDate>Tue, 18 Aug 2026 14:52:58 GMT</lastBuildDate><atom:link href="https://community.notepad-plus-plus.org/topic/22677.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 05 Mar 2022 20:34:42 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Generic Regex: Logic Gates for Regular Expressions on Sat, 05 Mar 2022 20:45:18 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/peterjones" aria-label="Profile: peterjones">@<bdi>peterjones</bdi></a> ,<br />
Thank you for this synopsis. This will take a little while to digest, but at least there is a succinct description we neophytes can come and  learn the way you explain things in detail. Thanks again.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/74943</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/74943</guid><dc:creator><![CDATA[Lycan Thrope]]></dc:creator><pubDate>Sat, 05 Mar 2022 20:45:18 GMT</pubDate></item></channel></rss>