-2

Given an expression such as

(exp(-((-mx + x - y)^2/(2 s1^2))2x - 2y (-my + y)^2/(2 s2^2)))/(2
pi sqrt(s1^2) sqrt(s2^2)

what is an easy way to detect all where multiply occurs? The above expression is uniquely defined. Variables cannot start with numbers and two variables multipled will always be separated by a space.

I.e. what regular expression (or other method) can be used to turn the above into

(exp(-((-mx + x - y)^2/(2*s1^2))*2*x - 2*y*(-my + y)^2/(2*s2^2)))/(2*
pi*sqrt(s1^2)*sqrt(s2^2)

Python or regex solution would be preferred.

Julius
  • 735
  • 2
  • 6
  • 17

1 Answers1

1

First, you should clearly define the situations when to insert a * and when not to, to avoid changing, e.g., exp( to e*x*p*(. Now, create a few regular expressions matching those situations.

patterns = [r"([0-9])\s*([a-z(])", # matches '2x', '2 x', or '2 ('
            r"([a-z])\s+([a-z])",  # matches 'x y', but not 'xy'
            r"([a-z])\s+(\()",     # matches 'x (', but not 'x('
            r"(\))\s*([0-9a-z(])"] # matches ')x', ')2', ') x', ') (', etc.

Use re.findall to test those. Finally, you have to replace those patterns in the expression. You can use re.sub with a replacement r"\1*\2". Here,\1 and \2 are the groups matched in the pattern.

expr = "(exp(-((-mx + x - y)^2/(2 s1^2))2x - 2y (-my + y)^2/(2 s2^2)))/(2pi sqrt(s1^2) sqrt(s2^2)"
for p in patterns:
    expr = re.sub(p, r"\1*\2", expr)

Afterwards, expr looks pretty much like the example in your question:

(exp(-((-mx + x - y)^2/(2*s1^2))*2*x - 2*y*(-my + y)^2/(2*s2^2)))/(2*pi*sqrt(s1^2)*sqrt(s2^2)
tobias_k
  • 81,265
  • 12
  • 120
  • 179
  • Thank you so much! I had to add these lines, but now it works. expr = expr.replace(' ','') expr = expr.replace(')(',')*(') expr = re.sub("([0-9])(\()", insert_mult, expr) # 2( – Julius Dec 02 '14 at 13:53
  • 1
    @Julius I added those cases to the first and fourth pattern. – tobias_k Dec 02 '14 at 14:00