Regular expression matching all but a string
<p>I need to find all the strings matching a pattern with the exception of two given strings. </p>

<p>For example, find all groups of letters with the exception of <code>aa</code> and <code>bb</code>. Starting from this string:</p>

<pre><code>-a-bc-aa-def-bb-ghij-
</code></pre>

<p>Should return:</p>

<pre><code>('a', 'bc', 'def', 'ghij')
</code></pre>

<p>I tried with <a href="http://pythex.org/?regex=-(%5Cw.*%3F)(%3F%3D-)&amp;test_string=-a-bc-def-ghij-&amp;ignorecase=0&amp;multiline=0&amp;dotall=0&amp;verbose=0" rel="nofollow">this regular</a> expression that captures 4 strings. I thought I was getting close, but (1) it doesn't work in Python and (2) I can't figure out how to exclude a few strings from the search. (Yes, I could remove them later, but my real regular expression does everything in one shot and I would like to include this last step in it.)</p>

<p>I said it doesn't work in Python because I tried this, expecting the exact same result, but instead I get only the first group:</p>

<pre><code>&gt;&gt;&gt; import re
&gt;&gt;&gt; re.search('-(\w.*?)(?=-)', '-a-bc-def-ghij-').groups()
('a',)
</code></pre>

<p>I tried with negative look ahead, but I couldn't find a working solution for this case.</p>

<p>You need to use a negative lookahead to restrict a more generic pattern, and a <code>re.findall</code> to find all matches.</p>

<p>Use</p>

<pre><code>res = re.findall(r'-(?!(?:aa|bb)-)(\w+)(?=-)', s)
</code></pre>

<p>or  - if your values in between hyphens can be any but a hyphen, use a negated character class <code>[^-]</code>:</p>

<pre><code>res = re.findall(r'-(?!(?:aa|bb)-)([^-]+)(?=-)', s)
</code></pre>

<p>Here is the <a href="https://regex101.com/r/eJ4uG7/2" rel="nofollow">regex demo</a>.</p>

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

<ul>
<li><code>-</code> - a hyphen</li>
<li><code>(?!(?:aa|bb)-)</code> - if there is a<code>aa-</code> or <code>bb-</code> after the first hyphen, no match should be returned</li>
<li><code>(\w+)</code> - Group 1 (this value will be returned by the <code>re.findall</code> call) capturing 1 or more word chars <strong>OR</strong> <code>[^-]+</code> - 1 or more characters other than <code>-</code></li>
<li><code>(?=-)</code> - there must be a <code>-</code> after the word chars. The lookahead is required here to ensure overlapping matches (as this hyphen will be a starting point for the next match).</li>
</ul>

<p><a href="http://ideone.com/qPZOny" rel="nofollow">Python demo</a>:</p>

<pre><code>import re
p = re.compile(r'-(?!(?:aa|bb)-)([^-]+)(?=-)')
s = "-a-bc-aa-def-bb-ghij-"
print(p.findall(s)) # =&gt; ['a', 'bc', 'def', 'ghij']
</code></pre>

python regex