title: RegExp replace only if not within <tag> and </tag>
body: <p>We are using a RegExp replace to searching a text for terms and wrap the hits with <code>&lt;dfn&gt;</code>. This works like a charm until we have a term that contains of several words that get wrapped and then a term that only has one of those words. For example:</p>
  
  <p>These are an example for one of these cases with the terms:<br>
  "Human Design System", "Design".</p>
  
  <p>So our code first finds "Human Design System", wraps it with a <code>&lt;dfn&gt;</code> tag and then finds "Design" within that and wraps that with an <code>&lt;dfn&gt;</code> tag.</p>
  
  <p>The result becomes:</p>
  
  <pre><code>&lt;dfn&gt;Human &lt;dfn&gt;Design&lt;/dfn&gt; System&lt;/dfn&gt;
  </code></pre>
  
  <p>When we desire the result:</p>
  
  <pre><code>&lt;dfn&gt;Human Design System&lt;/dfn&gt;
  </code></pre>
  
  <p>So what we need is a way of checking if the term is wrapped by a <code>&lt;dfn&gt;&lt;/dfn&gt;</code> and simply skip the replace for these cases.</p>
  
  <p>This is the code we are using right now:</p>
  
  <pre><code>//Definition of variables, please not that ~open~ is replaced by &lt;dfn&gt; and ~close~ is replaced by &lt;/dfn&gt; later  
  var TPL_TAG_OPEN = '~open~',
      TPL_TAG_CLOSE = '~close~',
      ESCAPERS = '[\\s!:\.\;,%\"\'\\(\\)\\{\\}]';
  
  //This is the RegExp that prepares the content
  //term is the term that we are looking for and line is the text we are searching in
  
  var re = new RegExp("^("+term+")(" + ESCAPERS + ")", modifier);
  line = line.replace(re, TPL_TAG_OPEN + "$1" + TPL_TAG_CLOSE + "$2");
  
  re = new RegExp("(" + ESCAPERS + ")("+term+")$", modifier);
  line = line.replace(re, "$1" + TPL_TAG_OPEN + "$2" + TPL_TAG_CLOSE);
  
  re = new RegExp("(" + ESCAPERS + ")("+term+")(" + ESCAPERS + ")", modifier);
  line = line.replace(re, "$1" + TPL_TAG_OPEN +"$2" + TPL_TAG_CLOSE + "$3");
  </code></pre>
  
  <p>Input:</p>
  
  <pre><code>&lt;dfn&gt;Human Design System&lt;/dfn&gt; Human Design Design Human Testar test Human Design Test 
  Human Test Design Test Test Design &lt;dfn&gt;Human Design System&lt;/dfn&gt; Test Human Design
  </code></pre>
  
  <p>Result right now:</p>
  
  <pre><code>&lt;dfn&gt;Human &lt;dfn&gt;Design&lt;/dfn&gt; System&lt;/dfn&gt; Human &lt;dfn&gt;Design&lt;/dfn &lt;dfn&gt;Design&lt;/dfn&gt; 
  Human Testar test Human &lt;dfn&gt;Design&lt;/dfn Test Human Test &lt;dfn&gt;Design&lt;/dfn&gt; Test Test
  &lt;dfn&gt;Design&lt;/dfn&gt; &lt;dfn&gt;Human &lt;dfn&gt;Design&lt;/dfn&gt; System&lt;/dfn&gt; Test Human &lt;dfn&gt;Design&lt;/dfn&gt;
  </code></pre>
  
  <p>Wanted Result:</p>
  
  <pre><code>&lt;dfn&gt;Human Design System&lt;/dfn&gt; Human &lt;dfn&gt;Design&lt;/dfn&gt; &lt;dfn&gt;Design&lt;/dfn&gt; 
  Human Testar test Human &lt;dfn&gt;Design&lt;/dfn&gt; Test Human Test &lt;dfn&gt;Design&lt;/dfn&gt; 
  Test Test &lt;dfn&gt;Design&lt;/dfn&gt; &lt;dfn&gt;Human Design System&lt;/dfn&gt; Test Human &lt;dfn&gt;Design&lt;/dfn&gt;
  </code></pre>
  
  <p>Note:</p>
  
  <p>We have succeeded to check if the term is wrapped by the tag already but only with the RegExp .test function, but if this will prevent the text to go on and check the rest of the text, here is that code:</p>
  
  <pre><code>var pattern = RegExp("^("+TPL_TAG_OPEN+").*((?!"+TPL_TAG_CLOSE+").).*("+term+")*$");
  
  if (pattern.test(line))
       return false;
  </code></pre>
  
  <p>Final solution:</p>
  
  <pre><code>var ESCAPERS = '[\\s!:\.\;,%\"\'\\(\\)\\{\\}]';
  var terms = ['Design','Human Design System','This and That...'];
  terms = terms.join('|');
  re = new RegExp("(" + ESCAPERS + "|^)(" + terms + ")(" + ESCAPERS + "|$)",'gi');
  nodes.contents().filter()
       .each(function(){
            $(this).replaceWith(this.nodeValue.replace(re, '$1&lt;dfn class=\"thesaurus\"&gt;$2&lt;/dfn&gt;$3'));
       });
  </code></pre>