Regex: exception to negative character class
<p>Using Python with Matthew Barnett's regex module.</p>

<p>I have this string:</p>

<pre><code>The well known *H*rry P*tter*.
</code></pre>

<p>I'm using this regex to process the asterisks to obtain <code>&lt;em&gt;H*rry P*tter&lt;/em&gt;</code>:</p>

<pre><code>REG = re.compile(r"""
(?&lt;!\p{L}|\p{N}|\\)
\*
([^\*]*?) # I need this part to deal with nested patterns; I really can't omit it
\*
(?!\p{L}|\p{N})
""", re.VERBOSE)
</code></pre>

<h3>PROBLEM</h3>

<p>The problem is that this regex doesn't match this kind of strings unless I protect intraword asterisks first (I convert them to decimal entities), which is awfully expensive in documents with lots of asterisks.</p>

<h3>QUESTION</h3>

<p>Is it possible to tell the negative class to block at internal asterisks <strong>only if</strong> they are not surrounded by word characters?</p>

<p>I tried these patterns in vain:</p>

<ul>
<li><code>([^(?:[^\p{L}|\p{N}]\*[^\p{L}|\p{N}])]*?)</code></li>
<li><code>([^(?&lt;!\p{L}\p{N})\*(?!\p{L}\p{N})]*?)</code></li>
</ul>

<p>I suggest a single regex replacement for the cases like you mentioned above:</p>

<pre><code>re.sub(r'\B\*\b([^*]*(?:\b\*\b[^*]*)*)\b\*\B', r'&lt;em&gt;\1&lt;/em&gt;', s)
</code></pre>

<p>See the <a href="https://regex101.com/r/SLEeCB/1" rel="nofollow">regex demo</a></p>

<p><strong>Details</strong>:</p>

<ul>
<li><code>\B\*\b</code> - a <code>*</code> that is preceded with a non-word boundary and followed with a word boundary</li>
<li><code>([^*]*(?:\b\*\b[^*]*)*)</code> - Group 1 capturing:

<ul>
<li><code>[^*]*</code> - 0+ chars other than <code>*</code></li>
<li><code>(?:\b\*\b[^*]*)*</code> - zero or more sequences of:

<ul>
<li><code>\b\*\b</code> - a <code>*</code> enclosed with word boundaries</li>
<li><code>[^*]*</code> - 0+ chars other than <code>*</code></li>
</ul></li>
</ul></li>
<li><code>\b\*\B</code> - a <code>*</code> that is followed with a non-word boundary and preceded with a word boundary</li>
</ul>

<p>More information on word boundaries and non-word boundaries:</p>

<ul>
<li><a href="http://www.regular-expressions.info/wordboundaries.html" rel="nofollow"><em>Word boundaries</em> at regular-expressions.info</a></li>
<li><a href="http://stackoverflow.com/questions/6664151/difference-between-b-and-b-in-regex"><em>Difference between <code>\b</code> and <code>\B</code> in regex</em></a></li>
<li><a href="http://stackoverflow.com/questions/4541573/what-are-non-word-boundary-in-regex-b-compared-to-word-boundary"><em>What are non-word boundary in regex (<code>\B</code>), compared to word-boundary?</em></a></li>
</ul>

python regex