How to write a regex for a text including comma separated values in python?
<p>I'm trying to write a regex in python to get F1 to F8 fields from a line that looks like this:</p>

<pre><code>LineNumber(digits): F1, F2, F3, ..., F8;
</code></pre>

<p><code>F1</code> to <code>F8</code> can have lowercase/uppercase letters and hyphens.</p>

<p>For example:</p>

<pre><code>Header
Description
21: Yes, No, Yes, No, Ye-s, N-o, YES, NO;
Footer
</code></pre>

<p>What I've tried so far is 
<code>matched = re.match(r'\d+: ([a-zA-Z-]*, ){7}(.*);', line)</code> which matches the lines with the above format. However, when I call <code>matched.groups()</code> to print the matched fields, I only get <code>F7,</code> and <code>F8</code> while the expected output is a list containing <code>F1,</code> to <code>F7,</code> plus <code>F8</code>.</p>

<p>I have a few questions regarding this regex:</p>

<ol>
<li><p>I guess <code>groups()</code> method returns the fields that were grouped in the regex using <code>(...)</code>. Why don't I get F1 to F6 in the output while they are grouped using <code>(...)</code> and have matched the regex?</p></li>
<li><p>What is a better regex I can write to exclude <code>,</code> from F1 to F7? (A short explanation of the suggested regex is much appreciated)</p></li>
</ol>

<p>When you have a construct like <code>(pattern){number}</code> then although it matches multiple instances, only the last one will be stored.  In other words, you get one bucket per <code>()</code>, even if you parse it multiple times, in which case the last instance is the one kept.  Note that you will get a bucket for ALL bracket pairs, even if they are not used, as in something like <code>(a(b)?c)?d</code> matching <code>d</code>.</p>

<p>If you know how many items to expect, then you can do your regexp the long way:</p>

<p><code>\d+: *([a-zA-Z-]+) *, *([a-zA-Z-]+) *, *([a-zA-Z-]+) *, *([a-zA-Z-]+) *, *([a-zA-Z-]+) *, *([a-zA-Z-]+) *, *([a-zA-Z-]+) *, *([a-zA-Z-]+) *;</code></p>

<p>This way, since you have 8 sets of brackets, you have 8 items in your <code>matched.groups()</code> array.  Also, we're not capturing the spaces and commas between the fields.</p>

<p>Given that your string is a CSV, you may be better off parsing it differently and splitting on commas rather than trying to have a single regexp to match the whole line.</p>

python regex csv