Wednesday, April 13, 2011

regular expression help with converting exp1^exp2 to pow(exp1, exp2)

I am converting some matlab code to C, currently I have some lines that have powers using the ^, which is rather easy to do with something along the lines \(?(\w*)\)?\^\(?(\w*)\)?

works fine for converting (glambda)^(galpha),using the sub routine in python pattern.sub(pow(\g<1>,\g<2>),'(glambda)^(galpha)')

My problem comes with nested parenthesis

So I have a string like:

glambdastar^(1-(1-gphi)*galpha)*(glambdaq)^(-(1-gphi)*galpha);

And I can not figure out how to convert that line to:

pow(glambdastar,(1-(1-gphi)*galpha))*pow(glambdaq,-(1-gphi)*galpha));

From stackoverflow
  • Nested parenthesis cannot be described by a regexp and require a full parser (able to understand a grammar, which is something more powerful than a regexp). I do not think there is a solution.

  • Unfortunately, regular expressions aren't the right tool for handling nested structures. There are some regular expressions engines (such as .NET) which have some support for recursion, but most — including the Python engine — do not, and can only handle as many levels of nesting as you build into the expression (which gets ugly fast).

    What you really need for this is a simple parser. For example, iterate over the string counting parentheses and storing their locations in a list. When you find a ^ character, put the most recently closed parenthesis group into a "left" variable, then watch the group formed by the next opening parenthesis. When it closes, use it as the "right" value and print the pow(left, right) expression.

  • See recent discussion function-parser-with-regex-in-python (one of many similar discussions). Then follow the suggestion to pyparsing.

  • An alternative would be to iterate until all ^ have been exhausted. no?.

    Ruby code:

    # assuming str contains the string of data with the expressions you wish to convert
    while str.include?('^')
      str!.gsub!(/(\w+)\^(\w+)/, 'pow(\1,\2)')
    end
    
  • I think you can use recursion here.

    Once you figure out the Left and Right parts, pass each of those to your function again. The base case would be that no ^ operator is found, so you will not need to add the pow() function to your result string.

    The function will return a string with all the correct pow()'s in place. I'll come up with an example of this if you want.

0 comments:

Post a Comment