def _expand_formula_(formula_string):
    """
    Accounts for the many ways a user may write a formula string, and returns an expanded chemical formula string.
    Assumptions:
    -The Chemical Formula string it is supplied is well-written, and has no hanging parethneses
    -The number of repeats occurs after the elemental symbol or ) ] character EXCEPT in the case of a hydrate where it is assumed to be in front of the first element
    -All hydrates explicitly use the · symbol
    -Only (, (,[, ], ., · are "important" symbols to intrepreting the string.
    -IONS ARE NOT HANDLED

    :param formula_string: a messy chemical formula string
    :return: a non-emperical but expanded formula string
    """
    formula_string = re.sub(r'[^A-Za-z0-9\(\)\[\]\·\.]+', '', formula_string)
    hydrate_pos = formula_string.find('·')
    if hydrate_pos >= 0:
        formula_string = _expand_hydrate_(hydrate_pos, formula_string)
    search_result = re.search(
        r'(?:[\(\[]([A-Za-z0-9]+)[\)\]](\d*))',
        formula_string)
    if search_result is None:
        return formula_string
    this_start = search_result.start()
    this_end = search_result.end()
    this_string = search_result.group()
    this_expansion_array = re.findall(
        r'(?:[\(\[]([A-Za-z0-9]+)[\)\]](\d*))', this_string)
    for a in this_expansion_array:
        if a[1] == "":
            a = (a[0], 1)
        parenth_expanded = ""
        multiplier = float(a[1])
        element_array = re.findall('[A-Z][^A-Z]*', a[0])
        for e in element_array:
            occurance_array = re.findall('[0-9][^0-9]*', e)
            if len(occurance_array) == 0:
                occurance_array.append(1)
            for o in occurance_array:
                symbol = re.findall('[A-Z][a-z]*', e)
                total_num = float(o) * multiplier
                if total_num.is_integer():
                    total_num = int(total_num)
                total_str = str(total_num)
                if total_str == "1":
                    total_str = ""
                new_string = symbol[0] + total_str
                parenth_expanded += new_string
        formula_string = formula_string[0:this_start] + \
            parenth_expanded + formula_string[this_end:]
        return _expand_formula_(formula_string)
def _expand_formula_ ( formula_string ) : formula_string = re . sub ( r'[^A-Za-z0-9\(\)\[\]\·\.]+' , '' , formula_string ) hydrate_pos = formula_string . find ( '·' ) if hydrate_pos >= 0 : formula_string = _expand_hydrate_ ( hydrate_pos , formula_string ) search_result = re . search ( r'(?:[\(\[]([A-Za-z0-9]+)[\)\]](\d*))' , formula_string ) if search_result is None : return formula_string this_start = search_result . start ( ) this_end = search_result . end ( ) this_string = search_result . group ( ) this_expansion_array = re . findall ( r'(?:[\(\[]([A-Za-z0-9]+)[\)\]](\d*))' , this_string ) for a in this_expansion_array : if a [ 1 ] == "" : a = ( a [ 0 ] , 1 ) parenth_expanded = "" multiplier = float ( a [ 1 ] ) element_array = re . findall ( '[A-Z][^A-Z]*' , a [ 0 ] ) for e in element_array : occurance_array = re . findall ( '[0-9][^0-9]*' , e ) if len ( occurance_array ) == 0 : occurance_array . append ( 1 ) for o in occurance_array : symbol = re . findall ( '[A-Z][a-z]*' , e ) total_num = float ( o ) * multiplier if total_num . is_integer ( ) : total_num = int ( total_num ) total_str = str ( total_num ) if total_str == "1" : total_str = "" new_string = symbol [ 0 ] + total_str parenth_expanded += new_string formula_string = formula_string [ 0 : this_start ] + parenth_expanded + formula_string [ this_end : ] return _expand_formula_ ( formula_string )
Accounts for the many ways a user may write a formula string, and returns an expanded chemical formula string.
    Assumptions:
    -The Chemical Formula string it is supplied is well-written, and has no hanging parethneses
    -The number of repeats occurs after the elemental symbol or ) ] character EXCEPT in the case of a hydrate where it is assumed to be in front of the first element
    -All hydrates explicitly use the · symbol
    -Only (, (,[, ], ., · are "important" symbols to intrepreting the string.
    -IONS ARE NOT HANDLED

    :param formula_string: a messy chemical formula string
    :return: a non-emperical but expanded formula string