<?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[Help how to find duplicate sentence]]></title><description><![CDATA[<p dir="auto">Help how to find duplicate sentence, means how to filter out repeated sentence or phrase in the notepad opened file, example</p>
<p dir="auto">abcde,abcde</p>
]]></description><link>https://community.notepad-plus-plus.org/topic/26124/help-how-to-find-duplicate-sentence</link><generator>RSS for Node</generator><lastBuildDate>Tue, 13 Oct 2026 06:06:48 GMT</lastBuildDate><atom:link href="https://community.notepad-plus-plus.org/topic/26124.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 18 Sep 2024 11:28:59 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Help how to find duplicate sentence on Wed, 18 Sep 2024 15:42:25 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/nasser-al-naamani" aria-label="Profile: NASSER-AL-NAAMANI">@<bdi>NASSER-AL-NAAMANI</bdi></a> ,</p>
<p dir="auto">You are way too vague for us to give a complete answer.  You say “sentence”, but then use an example of the single word <code>abcde</code> repeated.  Since we have no idea what characters are allowed in a sentence <em>for your data</em>, we would have to make our answer super-generic.  And because we don’t know whether they are always separated by just one character (like your example comma), or if it could have dozens of other “sentences” between, then we’d have to make it allow a generic amount of characters between.  The problem with super-generic regex that allow lots of variation in the number of characters between is that it’s an <em>exceedingly</em> inefficient regex, and if there are too many characters in your file, the regex engine can decide it’s out of memory/resources for it’s capture-and-backtrack algorithm, and stop before finding matches.</p>
<p dir="auto">If each of your “sentences” were a separate line of text, it would be much easier – and in fact, Notepad++ already has “Remove duplicate lines” or “Remove consecutive duplicate lines” built into the <strong>Search &gt; Line Operations</strong> menu.</p>
<p dir="auto">There’s also the matter of “filter out” – there are two ways to think of it: if there are two matching “sentences”, then “filter out” (delete) the second; or if there are two matching “sentences”, then “filter out” (delete) the first.  Both of those variants involve difficulties of their own.</p>
<p dir="auto">In general, the regex solution will involve the concepts of <a href="https://npp-user-manual.org/docs/searching/#capture-groups-and-backreferences" rel="nofollow ugc">capture groups and backreferenes</a>, and either a <a href="https://npp-user-manual.org/docs/searching/#assertions" rel="nofollow ugc">lookahead assertion</a> or (because true lookbehinds cannot be variable width) using the <a href="https://npp-user-manual.org/docs/searching/#control-flow:~:text=Resets%20matched%20text%20at%20this%20point" rel="nofollow ugc"><code>\K</code> control flow</a> to mimic a variable-width lookbehind.</p>
<p dir="auto">To do the delete-the-first, you would use a lookahead.  So it would end up being something <em>like</em></p>
<ul>
<li>FIND = <code>(.*)(?=.*?\1)</code><br />
REPLACE = &lt;leave empty&gt;<br />
SEARCH MODE = Regular Expression
<ul>
<li>the <code>(.*)</code> is the capture group, capturing just about anything of any length</li>
<li>the <code>(?=...)</code> is the lookahead, which means the characters have to match, but the replacement will not affect anything in that lookahead</li>
<li>the <code>.*?</code> inside the lookahead means “match anything in between”</li>
<li>the <code>\1</code> inside the lookahead means "match exactly the same text as was already matched in capture group 1</li>
</ul>
</li>
</ul>
<p dir="auto">To do the delete-the-second, you would want a lookbehind; but since the number of characters could be any length, you have to use <code>\K</code> to “reset” instead:</p>
<ul>
<li>FIND = <code>(.*).*?\K\1</code><br />
REPLACE = &lt;leave empty&gt;<br />
SEARCH MODE = Regular Expression
<ul>
<li>Must use REPLACE ALL; cannot do a whole bunch of single REPLACE, because using <code>\K</code></li>
<li>you might have to run it multiple times, because it may have advanced beyond the “first” of some matching pair when it did the previous.</li>
<li>the <code>\K</code> says “anything before the <code>\K</code> must match, but only stuff after the <code>\K</code> will be replaced by the REPLACE WITH text”</li>
<li>the other concepts are the same</li>
</ul>
</li>
</ul>
<p dir="auto">However, neither of those will <em>actually</em> work for you, because if your file was just the word <code>tenet</code>, either logic would see that the <code>t</code> is in your document twice, and delete one of them; then would see that <code>e</code> was in the document twice, and delete one of those, too.  So with the delete-the-first solution, you’d end up with <code>net</code>; if you used the delete-the-second solution, the first time you REPLACE ALL, it would delete the <code>t</code> at the end, to produce <code>tene</code>, and then running it a second time, it would delete the <code>e</code> at the end, to produce <code>ten</code> . Even worse, the document <code>tenet is a funny word, but it is a word.</code> would end up with <code>ten isafuyword,b.</code> using the delete-the-second, and <code>efny,butisa word.</code> using the first.</p>
<p dir="auto">If that’s not the weird results you want, then you’d have to make some sort of real regex definition for a “sentence”.  And that’s more difficult that you might think.  And I am quite certain, for any definition or regex that you think you had which would reliably match a sentence, I could come up with an exception that your definition/regex doesn’t cover.  But if by some miracle, you <em>could</em> come up with a definition for a sentence or phrase that works for you in <em>all</em> edge cases, you would put it inside the first parentheses in one of the two regex I showed above.</p>
<p dir="auto">To give more examples of why you are likely to not find what you want:</p>
<ol>
<li>
<p dir="auto">Using the definition of “a ‘sentence or phrase’` is any whole word (set of word characters between word boundaries) followed by <em>anything</em> else”, then</p>
<ul>
<li>delete-the-first: FIND = <code>(\b\w+\b.*)(?=.*?\1)</code> , which would transform <code>tenet is a funny word, but it is a word.</code> into <code>tenet funny , but it is a word.</code></li>
<li>delete-the-second: FIND = <code>(\b\w+\b.*).*?\K\1</code>, which would result in <code>tenet is a funny word, but it .</code></li>
</ul>
</li>
<li>
<p dir="auto">Using the definition of "a ‘sentence or phrase’` is two or more whole words (set of word characters between word boundaries) separated by only spaces:</p>
<ul>
<li>delete-the-first: FIND = <code>(\b\w+\b.*)(?=.*?\1)</code> , which would transform <code>tenet is a funny word, but it is a word.</code> into <code>tenet  funny word, but it is a word.</code></li>
<li>delete-the-second: FIND = <code>(\b\w+\b(?:\h+\b\w+\b)+).*?\K\1</code>, which would result in <code>tenet is a funny word, but it  word.</code></li>
<li>this deleted just the phrase <code>is a</code> , which meets your generic phrasing of “sentence or phrase”.</li>
</ul>
</li>
</ol>
<p dir="auto">I’m not sure anything much more complicated would truly get better, and I am sure you’d run across weird exceptions the more complicated you got.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/96661</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/96661</guid><dc:creator><![CDATA[PeterJones]]></dc:creator><pubDate>Wed, 18 Sep 2024 15:42:25 GMT</pubDate></item></channel></rss>