title: Parsing a chemical formula from a string in C#?
body: <p>I am trying to parse a chemical formula (in the format, for example: <code>Al2O3</code> or <code>O3</code> or <code>C</code> or <code>C11H22O12</code>) in C# from a string. It works fine unless there is only one atom of a particular element (e.g. the oxygen atom in <code>H2O</code>). How can I fix that problem, and in addition, is there a better way to parse a chemical formula string than I am doing?</p>
  
  <p>ChemicalElement is a class representing a chemical element. It has properties AtomicNumber (int), Name (string), Symbol (string).
  ChemicalFormulaComponent is a class representing a chemical element and atom count (e.g. part of a formula). It has properties Element (ChemicalElement), AtomCount (int).</p>
  
  <p>The rest should be clear enough to understand (I hope) but please let me know with a comment if I can clarify anything, before you answer.</p>
  
  <p>Here is my current code:</p>
  
  <pre><code>    /// &lt;summary&gt;
      /// Parses a chemical formula from a string.
      /// &lt;/summary&gt;
      /// &lt;param name="chemicalFormula"&gt;The string to parse.&lt;/param&gt;
      /// &lt;exception cref="FormatException"&gt;The chemical formula was in an invalid format.&lt;/exception&gt;
      public static Collection&lt;ChemicalFormulaComponent&gt; FormulaFromString(string chemicalFormula)
      {
          Collection&lt;ChemicalFormulaComponent&gt; formula = new Collection&lt;ChemicalFormulaComponent&gt;();
  
          string nameBuffer = string.Empty;
          int countBuffer = 0;
  
          for (int i = 0; i &lt; chemicalFormula.Length; i++)
          {
              char c = chemicalFormula[i];
  
              if (!char.IsLetterOrDigit(c) || !char.IsUpper(chemicalFormula, 0))
              {
                  throw new FormatException("Input string was in an incorrect format.");
              }
              else if (char.IsUpper(c))
              {
                  // Add the chemical element and its atom count
                  if (countBuffer &gt; 0)
                  {
                      formula.Add(new ChemicalFormulaComponent(ChemicalElement.ElementFromSymbol(nameBuffer), countBuffer));
  
                      // Reset
                      nameBuffer = string.Empty;
                      countBuffer = 0;
                  }
  
                  nameBuffer += c;
              }
              else if (char.IsLower(c))
              {
                  nameBuffer += c;
              }
              else if (char.IsDigit(c))
              {
                  if (countBuffer == 0)
                  {
                      countBuffer = c - '0';
                  }
                  else
                  {
                      countBuffer = (countBuffer * 10) + (c - '0');
                  }
              }
          }
  
          return formula;
      }
  </code></pre>