title: What is the best way to censor inappropriate words that might contain markup within them?
body: <p>I run a large website that contains millions of user generated posts that contain HTML.  Some of these posts contain sensitive words my advertisers don't want to advertise next to.  Instead of deleting these posts, I'd rather censor out the "bad" words.  I also need to preserve the markup because letting the users mark up their posts is a major feature of the site.</p>
  
  <p>I am currently using a search and replace with <code>str_ireplace()</code>, but our authors have become clever and are doing things (below) that slip through my primitive filter.  I can strip the tags and <em>detect</em> the inappropriate words, but am looking for a way of replacing the words while leaving the markup untouched.</p>
  
  <p>Examples:</p>
  
  <p>Successfully censored:</p>
  
  <pre><code>input:  "&lt;p&gt;Mary is a bitch.&lt;/p&gt;"
  output: "&lt;p&gt;Mary is a *****.&lt;/p&gt;" 
  </code></pre>
  
  <p>Unsuccessfully censored:</p>
  
  <pre><code>input:          "&lt;p&gt;Mary is a &lt;strong&gt;b&lt;/strong&gt;itch.&lt;/p&gt;"
  failed output:  "&lt;p&gt;Mary is a &lt;strong&gt;b&lt;/strong&gt;itch.&lt;/p&gt;" 
  desired output: "&lt;p&gt;Mary is a &lt;strong&gt;*&lt;/strong&gt;****.&lt;/p&gt;"
  </code></pre>