title: How to parse a CSV with commas between parenthesis and missing values
body: <p>I tried using <code>pyparsing</code> to parse a CSV with:</p>
  
  <ul>
  <li><strong>Commas between parenthesis (or brackets, etc):</strong> "a(1,2),b" should return the list ["a(1,2)","b"]</li>
  <li><strong>Missing values:</strong> "a,b,,c," should return the list ['a','b','','c','']</li>
  </ul>
  
  <p>I worked a solution but it seems "dirty". Mainly, the <code>Optional</code> inside only one of the possible atomics. I think the optional should be independent of the atomics. That is, I feel it should be put somewhere else, for example in the <code>delimitedList</code> optional arguments, but in my trial and error that was the only place that worked and made sense. It could be in any of the possible atomics so I chose the first. </p>
  
  <p>Also, I don't fully understand what <code>originalTextFor</code> is doing but if I remove it it stops working.</p>
  
  <p>Working example:</p>
  
  <pre><code>import pyparsing as pp
  
  # Function that parses a line of columns separated by commas and returns a list of the columns
  def fromLineToRow(line):
      sqbrackets_col = pp.Word(pp.printables, excludeChars="[],") | pp.nestedExpr(opener="[",closer="]")  # matches "a[1,2]"
      parens_col = pp.Word(pp.printables, excludeChars="(),") | pp.nestedExpr(opener="(",closer=")")      # matches "a(1,2)"
      # In the following line:
      # * The "^" means "choose the longest option"
      # * The "pp.Optional" can be in any of the expressions separated by "^". I put it only on the first. It's used for when there are missing values
      atomic = pp.originalTextFor(pp.Optional(pp.OneOrMore(parens_col))) ^ pp.originalTextFor(pp.OneOrMore(sqbrackets_col))
  
      grammar = pp.delimitedList(atomic)
  
      row = grammar.parseString(line).asList()
      return row
  
  file_str = \
  """YEAR,a(2,3),b[3,4]
  1960,2.8,3
  1961,4,
  1962,,1
  1963,1.27,3"""
  
  for line in file_str.splitlines():
      row = fromLineToRow(line)
      print(row)
  </code></pre>
  
  <p>Prints:</p>
  
  <pre><code>['YEAR', 'a(2,3)', 'b[3,4]']
  ['1960', '2.8', '3']
  ['1961', '4', '']
  ['1962', '', '1']
  ['1963', '1.27', '3']
  </code></pre>
  
  <p>Is this the right way to do this? Is there a "cleaner" way to use the <code>Optional</code> inside the first atomic?</p>