def build_reaction_from_string(self, reaction_str, verbose=True,<EOL>fwd_arrow=None, rev_arrow=None,<EOL>reversible_arrow=None, term_split="<STR_LIT:+>"):
<EOL>forward_arrow_finder = _forward_arrow_finder if fwd_arrow is Noneelse re.compile(re.escape(fwd_arrow))<EOL>reverse_arrow_finder = _reverse_arrow_finder if rev_arrow is Noneelse re.compile(re.escape(rev_arrow))<EOL>reversible_arrow_finder = _reversible_arrow_finderif reversible_arrow is Noneelse re.compile(re.escape(reversible_arrow))<EOL>if self._model is None:<EOL><INDENT>warn("<STR_LIT>")<EOL>model = None<EOL><DEDENT>else:<EOL><INDENT>model = self._model<EOL><DEDENT>found_compartments = compartment_finder.findall(reaction_str)<EOL>if len(found_compartments) == <NUM_LIT:1>:<EOL><INDENT>compartment = found_compartments[<NUM_LIT:0>]<EOL>reaction_str = compartment_finder.sub("<STR_LIT>", reaction_str)<EOL><DEDENT>else:<EOL><INDENT>compartment = "<STR_LIT>"<EOL><DEDENT>arrow_match = reversible_arrow_finder.search(reaction_str)<EOL>if arrow_match is not None:<EOL><INDENT>self.lower_bound = -<NUM_LIT:1000><EOL>self.upper_bound = <NUM_LIT:1000><EOL><DEDENT>else:  <EOL><INDENT>arrow_match = forward_arrow_finder.search(reaction_str)<EOL>if arrow_match is not None:<EOL><INDENT>self.upper_bound = <NUM_LIT:1000><EOL>self.lower_bound = <NUM_LIT:0><EOL><DEDENT>else:<EOL><INDENT>arrow_match = reverse_arrow_finder.search(reaction_str)<EOL>if arrow_match is None:<EOL><INDENT>raise ValueError("<STR_LIT>" %<EOL>reaction_str)<EOL><DEDENT>else:<EOL><INDENT>self.upper_bound = <NUM_LIT:0><EOL>self.lower_bound = -<NUM_LIT:1000><EOL><DEDENT><DEDENT><DEDENT>reactant_str = reaction_str[:arrow_match.start()].strip()<EOL>product_str = reaction_str[arrow_match.end():].strip()<EOL>self.subtract_metabolites(self.metabolites, combine=True)<EOL>for substr, factor in ((reactant_str, -<NUM_LIT:1>), (product_str, <NUM_LIT:1>)):<EOL><INDENT>if len(substr) == <NUM_LIT:0>:<EOL><INDENT>continue<EOL><DEDENT>for term in substr.split(term_split):<EOL><INDENT>term = term.strip()<EOL>if term.lower() == "<STR_LIT>":<EOL><INDENT>continue<EOL><DEDENT>if "<STR_LIT:U+0020>" in term:<EOL><INDENT>num_str, met_id = term.split()<EOL>num = float(num_str.lstrip("<STR_LIT:(>").rstrip("<STR_LIT:)>")) * factor<EOL><DEDENT>else:<EOL><INDENT>met_id = term<EOL>num = factor<EOL><DEDENT>met_id += compartment<EOL>try:<EOL><INDENT>met = model.metabolites.get_by_id(met_id)<EOL><DEDENT>except KeyError:<EOL><INDENT>if verbose:<EOL><INDENT>print("<STR_LIT>" % met_id)<EOL><DEDENT>met = Metabolite(met_id)<EOL><DEDENT>self.add_metabolites({met: num})<EOL><DEDENT><DEDENT>
Builds reaction from reaction equation reaction_str using parser

        Takes a string and using the specifications supplied in the optional
        arguments infers a set of metabolites, metabolite compartments and
        stoichiometries for the reaction.  It also infers the reversibility
        of the reaction from the reaction arrow.

        Changes to the associated model are reverted upon exit when using
        the model as a context.

        Parameters
        ----------
        reaction_str : string
            a string containing a reaction formula (equation)
        verbose: bool
            setting verbosity of function
        fwd_arrow : re.compile
            for forward irreversible reaction arrows
        rev_arrow : re.compile
            for backward irreversible reaction arrows
        reversible_arrow : re.compile
            for reversible reaction arrows
        term_split : string
            dividing individual metabolite entries