Converting a string into list of desired tokens using python
<p>I have ingredients for thousands of products for example:</p>

<pre><code>Ingredient = 'Beef stock (beef bones, water, onion, carrot, beef meat, parsnip, thyme, parsley, clove, black pepper, bay leaf), low lactose cream (28%), onion, mustard, modified maize starch,tomato puree, modified potato starch, butter sugar, salt (0,8%), burnt sugar, blackcurrant, peppercorns (black, pink, green, all spice, white) 0,4%.'
</code></pre>

<p>I want this ingredient in the form of a list like the following:</p>

<pre><code>listOfIngredients = ['Beef Stock', 'low lactose cream', 'onion', 'mustard', 'modified maize starch','tomato puree', 'modified potato starch', 'butter sugar', 'salt', 'burnt sugar', 'blackcurrant', 'peppercorns']
</code></pre>

<p>So in the listOfIngredients I do not have any explanations of the product in percentage or even further products that one ingredient itself contains. Regex is a good way of doing this but I am not good at making regex. Can someone help me in making regex to get the desired output. Thanks in advance. </p>

<p>You might try two approaches.</p>

<p>The first one is to remove all <code>(...)</code> substrings and anything that is not <code>,</code> after (that is not followed with non-word boundary).</p>

<pre><code>\s*\([^()]*\)[^,]*(?:,\b[^,]*)*
</code></pre>

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

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

<ul>
<li><code>\s*</code> - 0+ whitespaces</li>
<li><code>\([^()]*\)</code> - a <code>(...)</code> substring having no <code>(</code> and <code>)</code> inside: 

<ul>
<li><code>\(</code> - a literal <code>(</code></li>
<li><code>[^()]*</code> - 0+ chars other than <code>(</code> and <code>)</code> (a <code>[^...]</code> is a <em>negated character class</em>)</li>
</ul></li>
<li><code>[^,]*</code> - 0+ chars other than <code>,</code></li>
<li><code>(?:,\b[^,]*)*</code> - zero or more sequences of:

<ul>
<li><code>,\b</code> - a comma that is followed with a letter/digit/underscore</li>
<li><code>[^,]*</code> - 0+ chars other than <code>,</code>.</li>
</ul></li>
</ul>

<p>These matches are removed, and then <code>,\s*</code> regex is used to split the string with a comma and 0+ whitespaces to get the final result.</p>

<p>The second one is based on matching and <em>capturing</em> words consisting of letters (and <code>_</code>) only, and just matching  <code>(...)</code> substrings.</p>

<pre><code>\([^()]*\)|([^\W\d]+(?:\s+[^\W\d]+)*)
</code></pre>

<p>See the <a href="http://%5C([%5E()]*%5C)%7C([%5E%5CW%5Cd]+(?:%5Cs%20[%5E%5CW%5Cd]%20)*)" rel="nofollow">second regex demo</a></p>

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

<ul>
<li><code>\([^()]*\)</code> - a <code>(...)</code> substring having no <code>(</code> and <code>)</code> inside</li>
<li><code>|</code> - or </li>
<li><code>([^\W\d]+(?:\s+[^\W\d]+)*)</code> - Group 1 capturing:

<ul>
<li><code>[^\W\d]+</code> - 1+ letters or underscores (you may add <code>_</code> after <code>\d</code> to exclude underscores)</li>
<li><code>(?:\s+[^\W\d]+)*</code> - 0+ sequences of:

<ul>
<li><code>\s+</code> - 1 or more whitespaces</li>
<li><code>[^\W\d]+</code> - 1+ letters or underscores</li>
</ul></li>
</ul></li>
</ul>

<p>Both return the same results for the current string, but you may want to adjust it in future.</p>

<p>See <a href="https://ideone.com/KJdUOb" rel="nofollow">Python demo</a>:</p>

<pre><code>import re
Ingredient = 'Beef stock (beef bones, water, onion, carrot, beef meat, parsnip, thyme, parsley, clove, black pepper, bay leaf), low lactose cream (28%), onion, mustard, modified maize starch,tomato puree, modified potato starch, butter sugar, salt (0,8%), burnt sugar, blackcurrant, peppercorns (black, pink, green, all spice, white) 0,4%.'
res = re.sub(r'\s*\([^()]*\)[^,]*(?:,\b[^,]*)*', "", Ingredient)
print(re.split(r',\s*', res))

vals = re.findall(r'\([^()]*\)|([^\W\d]+(?:\s+[^\W\d]+)*)', Ingredient)
vals = [x for x in vals if x]
print(vals)
</code></pre>

python regex