Equations with Regular Expressions

Nick Mathewson QnickQm at alum.mit.edu
Wed Feb 27 12:07:39 EST 2002


In article <mailman.1014805905.18241.python-list at python.org>, 
         Alves, Carlos Alberto - Coelce wrote:
> Hi everybody,

Hello there!

> Could someone of you give me and example of how can I translate
> '2x^3-2x^2+15' into '2*(x**3)-2*(x**2)+15' using regular expressions.

I can't tell (from the form of your problem) what kind of inputs you're
expecting.  Do you have to accept:
   1) Polynomials in a single variable?
   2) Arbitrary expressions?
   3) Something else entirely?

Here's the beginnings of a general solution you can use.  It accepts
a parenthesized algebraic expression of single-letter variables, and
turns in into a Python expression.  

It doesn't do _exactly_ what you want: it doesn't put parenthesis
around the ** operator.  (e.g., you asked for "2x^2"--> "2*(x**2)",
but this code gives "2*x**2.") I'm leaving this out because ** has
precedence over * in Python, and so the two expressions above are
equivalent anyway.

This code requires Python 2.0 or higher.

(I wouldn't do it this way in real life; I'd probably use more code to
write a tokenizer instead and try to do real re manipulation. Your
solution asked for a regular expression, though, so that's what you'll
get. :) )

=======================================================================
import re


# Translation is for the most part easy: Just turn all '^' into 
# "**", and insert a "*" between:
#            A number, variable, or close paren followed by an
#             open paren, number, or variable.

#
# This re matches 
#      1) a number when it's followed by a ( or a variable,
#   or 2) A ) or a variable when it's followed by a (, a number, or a variable.
#
boundary_re = re.compile(r'''(
                               (?:\d+(?:\.\d*)?|\.\d+)\s*
                               (?=\(|[A-Za-z])
                            |
                               (?:\)|[A-Za-z])\s*
                               (?=\(|\d+(?:\.\d*)?|\.\d+|[A-Za-z])
                             )''', re.X)

def translate(string):
    s2 = boundary_re.sub(r'\1*', string)
    return s2.replace("^", "**")

if __name__ == '__main__':
    print translate("1")
    print translate("")
    print translate("x")
    print translate("x+y")
    print translate("xy")
    print translate("5x^(3xy)+9x/4")
    print translate('2x^3-2x^2+15')

=======================================================================
Pretty-sure-that-putting-explicit-parenthesis-around-the-exponentiations-
  would-require-a-real-tokenizer-ly yrs,
 						Nick



More information about the Python-list mailing list